- implementation of RtlReg* (read access), RtlEvent*, RtlSemaphore*,
  NtAllocateLocallyUniqueId
- implementation or stubs for NtAccessCheck, NtSetSecurityObject,
  RtlClearBits, RtlEqualPrefixSid, RtlFindClearBits,
  RtlFormatCurrentUserKeyPath, RtlGetControlSecurityDescriptor,
  RtlIdentifierAuthoritySid, RtlImpersonateSelf, RtlInitializeBitMap,
  RtlInitializeGenericTable, RtlMakeSelfRelativeSD,
  RtlPrefixUnicodeString, RtlSetBits, RtlUnicodeToMultiByteN,
  RtlUpcaseUnicodeStringToOemString, RtlUpcaseUnicodeToOemN,
  RtlValidSid, RtlxUnicodeStringToOemSize
- corrected most RtlString* functions, added documentation
- more fixes and partial implementations

diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
index 2c478f4..0d266a5 100644
--- a/dlls/advapi32/advapi32.spec
+++ b/dlls/advapi32/advapi32.spec
@@ -112,7 +112,7 @@
 @ stub ImpersonateLoggedOnUser
 @ stub ImpersonateNamedPipeClient
 @ stdcall ImpersonateSelf(long) ImpersonateSelf
-@ stub InitializeAcl
+@ stdcall InitializeAcl(ptr long long) InitializeAcl
 @ stdcall InitializeSecurityDescriptor(ptr long) InitializeSecurityDescriptor
 @ stdcall InitializeSid(ptr ptr long) InitializeSid
 @ stub InitiateSystemShutdownA
@@ -224,7 +224,7 @@
 @ stub SetAclInformation
 @ stdcall SetFileSecurityA(str long ptr ) SetFileSecurityA
 @ stdcall SetFileSecurityW(wstr long ptr) SetFileSecurityW
-@ stub SetKernelObjectSecurity
+@ stdcall SetKernelObjectSecurity(long long ptr) SetKernelObjectSecurity
 @ stub SetPrivateObjectSecurity
 @ stdcall SetSecurityDescriptorDacl(ptr long ptr long) SetSecurityDescriptorDacl
 @ stdcall SetSecurityDescriptorGroup (ptr ptr long) SetSecurityDescriptorGroup
@@ -241,7 +241,7 @@
 @ stdcall StartServiceW(long long ptr) StartServiceW
 @ stub UnlockServiceDatabase
 @ stdcall LsaOpenPolicy(long long long long) LsaOpenPolicy
-@ stub LsaLookupSids
+@ stdcall LsaLookupSids(ptr long ptr ptr ptr) LsaLookupSids
 @ stdcall LsaFreeMemory(ptr)LsaFreeMemory
 @ stdcall LsaQueryInformationPolicy(ptr long ptr)LsaQueryInformationPolicy
 @ stdcall LsaClose(ptr)LsaClose
diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c
index 1e61f1b..d98fe65 100644
--- a/dlls/advapi32/security.c
+++ b/dlls/advapi32/security.c
@@ -10,24 +10,11 @@
 #include "ntddk.h"
 #include "ntsecapi.h"
 #include "debugtools.h"
+#include "winversion.h"
 
 DEFAULT_DEBUG_CHANNEL(advapi)
 DECLARE_DEBUG_CHANNEL(security)
 
-
-static BOOL Wine_HasSecurity(void)
-{
-    OSVERSIONINFOA osi;
-    osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); 
-    GetVersionExA(&osi);
-    if (osi.dwPlatformId != VER_PLATFORM_WIN32_NT) { 
-        SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 
-        return FALSE;
-    }
-    return TRUE;
-}  
-
-
 #define CallWin32ToNt(func) \
 	{ NTSTATUS ret; \
 	  ret = (func); \
@@ -36,6 +23,17 @@
 	  return TRUE; \
 	}
 
+static void dumpLsaAttributes( PLSA_OBJECT_ATTRIBUTES oa )
+{
+	if (oa)
+	{
+	  TRACE("\n\tlength=%lu, rootdir=0x%08x, objectname=%s\n\tattr=0x%08lx, sid=%p qos=%p\n",
+		oa->Length, oa->RootDirectory,
+		oa->ObjectName?debugstr_w(oa->ObjectName->Buffer):"null",
+     		oa->Attributes, oa->SecurityDescriptor, oa->SecurityQualityOfService);
+	}
+}
+
 /*	##############################
 	######	TOKEN FUNCTIONS ######
 	##############################
@@ -56,7 +54,6 @@
 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess, 
                   HANDLE *TokenHandle )
 {
-        if (!Wine_HasSecurity()) return FALSE;
 	CallWin32ToNt(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
 }
 
@@ -73,7 +70,6 @@
 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess, 
 		 BOOL OpenAsSelf, HANDLE *TokenHandle)
 {
-        if (!Wine_HasSecurity()) return FALSE;
 	CallWin32ToNt (NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
 }
 
@@ -114,6 +110,25 @@
 	CallWin32ToNt (NtQueryInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength, retlen));
 }
 
+/*************************************************************************
+ * SetThreadToken [ADVAPI32.231]
+ *
+ * Assigns an "impersonation token" to a thread so it can assume the
+ * security privledges of another thread or process.  Can also remove
+ * a previously assigned token.  Only supported on NT - it's a stub 
+ * exactly like this one on Win9X.
+ *
+ */
+
+BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
+{
+    FIXME("(%p, %x): stub\n", thread, token);
+
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+
+    return FALSE;
+}
+
 /*	##############################
 	######	SID FUNCTIONS	######
 	##############################
@@ -144,33 +159,11 @@
                           DWORD nSubAuthority6, DWORD nSubAuthority7,
                           PSID *pSid )
 {
-    if (!(*pSid = HeapAlloc( GetProcessHeap(), 0,
-                             GetSidLengthRequired(nSubAuthorityCount))))
-        return FALSE;
-    (*pSid)->Revision = SID_REVISION;
-    if (pIdentifierAuthority)
-        memcpy(&(*pSid)->IdentifierAuthority, pIdentifierAuthority,
-               sizeof (SID_IDENTIFIER_AUTHORITY));
-    *GetSidSubAuthorityCount(*pSid) = nSubAuthorityCount;
-
-    if (nSubAuthorityCount > 0)
-        *GetSidSubAuthority(*pSid, 0) = nSubAuthority0;
-    if (nSubAuthorityCount > 1)
-        *GetSidSubAuthority(*pSid, 1) = nSubAuthority1;
-    if (nSubAuthorityCount > 2)
-        *GetSidSubAuthority(*pSid, 2) = nSubAuthority2;
-    if (nSubAuthorityCount > 3)
-        *GetSidSubAuthority(*pSid, 3) = nSubAuthority3;
-    if (nSubAuthorityCount > 4)
-        *GetSidSubAuthority(*pSid, 4) = nSubAuthority4;
-    if (nSubAuthorityCount > 5)
-        *GetSidSubAuthority(*pSid, 5) = nSubAuthority5;
-    if (nSubAuthorityCount > 6)
-        *GetSidSubAuthority(*pSid, 6) = nSubAuthority6;
-    if (nSubAuthorityCount > 7)
-        *GetSidSubAuthority(*pSid, 7) = nSubAuthority7;
-
-    return TRUE;
+	CallWin32ToNt (RtlAllocateAndInitializeSid(
+		pIdentifierAuthority, nSubAuthorityCount, 
+		nSubAuthority0, nSubAuthority1,	nSubAuthority2, nSubAuthority3,
+		nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
+		pSid ));
 }
 
 /******************************************************************************
@@ -182,8 +175,8 @@
 PVOID WINAPI
 FreeSid( PSID pSid )
 {
-    HeapFree( GetProcessHeap(), 0, pSid );
-    return NULL;
+    	RtlFreeSid(pSid); 
+	return NULL; /* is documented like this */
 }
 
 /******************************************************************************
@@ -197,16 +190,7 @@
 BOOL WINAPI
 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
 {
-
-    if (!IsValidSid(pSourceSid))
-        return FALSE;
-
-    if (nDestinationSidLength < GetLengthSid(pSourceSid))
-        return FALSE;
-
-    memcpy(pDestinationSid, pSourceSid, GetLengthSid(pSourceSid));
-
-    return TRUE;
+	return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
 }
 
 /******************************************************************************
@@ -218,19 +202,7 @@
 BOOL WINAPI
 IsValidSid( PSID pSid )
 {
-    if (IsBadReadPtr(pSid, 4))
-    {
-        WARN_(security)("(%p): invalid pointer!", pSid);
-        return FALSE;
-    }
-
-    if (pSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
-        return FALSE;
-
-    if (!pSid || pSid->Revision != SID_REVISION)
-        return FALSE;
-
-    return TRUE;
+	return RtlValidSid( pSid );
 }
 
 /******************************************************************************
@@ -243,33 +215,15 @@
 BOOL WINAPI
 EqualSid( PSID pSid1, PSID pSid2 )
 {
-    if (!IsValidSid(pSid1) || !IsValidSid(pSid2))
-        return FALSE;
-
-    if (*GetSidSubAuthorityCount(pSid1) != *GetSidSubAuthorityCount(pSid2))
-        return FALSE;
-
-    if (memcmp(pSid1, pSid2, GetLengthSid(pSid1)) != 0)
-        return FALSE;
-
-    return TRUE;
+	return RtlEqualSid( pSid1, pSid2 );
 }
 
 /******************************************************************************
  * EqualPrefixSid [ADVAPI32.39]
  */
-BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2) {
-    if (!IsValidSid(pSid1) || !IsValidSid(pSid2))
-        return FALSE;
-
-    if (*GetSidSubAuthorityCount(pSid1) != *GetSidSubAuthorityCount(pSid2))
-        return FALSE;
-
-    if (memcmp(pSid1, pSid2, GetSidLengthRequired(pSid1->SubAuthorityCount - 1))
- != 0)
-        return FALSE;
-
-    return TRUE;
+BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2) 
+{
+	return RtlEqualPrefixSid(pSid1, pSid2);
 }
 
 /******************************************************************************
@@ -281,7 +235,7 @@
 DWORD WINAPI
 GetSidLengthRequired( BYTE nSubAuthorityCount )
 {
-    return sizeof (SID) + (nSubAuthorityCount - 1) * sizeof (DWORD);
+	return RtlLengthRequiredSid(nSubAuthorityCount);
 }
 
 /******************************************************************************
@@ -291,21 +245,12 @@
  *   pIdentifierAuthority []
  */
 BOOL WINAPI
-InitializeSid (PSID pSid, PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
-                    BYTE nSubAuthorityCount)
+InitializeSid (
+	PSID pSid,
+	PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
+	BYTE nSubAuthorityCount)
 {
-    int i;
-
-    pSid->Revision = SID_REVISION;
-    if (pIdentifierAuthority)
-        memcpy(&pSid->IdentifierAuthority, pIdentifierAuthority,
-               sizeof (SID_IDENTIFIER_AUTHORITY));
-    *GetSidSubAuthorityCount(pSid) = nSubAuthorityCount;
-
-    for (i = 0; i < nSubAuthorityCount; i++)
-        *GetSidSubAuthority(pSid, i) = 0;
-
-    return TRUE;
+	return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
 }
 
 /******************************************************************************
@@ -317,7 +262,7 @@
 PSID_IDENTIFIER_AUTHORITY WINAPI
 GetSidIdentifierAuthority( PSID pSid )
 {
-    return &pSid->IdentifierAuthority;
+	return RtlIdentifierAuthoritySid(pSid);
 }
 
 /******************************************************************************
@@ -330,7 +275,7 @@
 PDWORD WINAPI
 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
 {
-    return &pSid->SubAuthority[nSubAuthority];
+	return RtlSubAuthoritySid(pSid, nSubAuthority);
 }
 
 /******************************************************************************
@@ -342,7 +287,7 @@
 PUCHAR WINAPI
 GetSidSubAuthorityCount (PSID pSid)
 {
-    return &pSid->SubAuthorityCount;
+	return RtlSubAuthorityCountSid(pSid);
 }
 
 /******************************************************************************
@@ -354,7 +299,7 @@
 DWORD WINAPI
 GetLengthSid (PSID pSid)
 {
-    return GetSidLengthRequired( * GetSidSubAuthorityCount(pSid) );
+	return RtlLengthSid(pSid);
 }
 
 /*	##############################################
@@ -472,14 +417,14 @@
 	OUT PACL *pSacl,
 	OUT LPBOOL lpbSaclDefaulted)
 {
-	CallWin32ToNt (RtlGetSaclSecurityDescriptor(lpsd, (PBOOLEAN)lpbSaclPresent,
-					       pSacl, (PBOOLEAN)lpbSaclDefaulted));
+	CallWin32ToNt (RtlGetSaclSecurityDescriptor(lpsd,
+	   (PBOOLEAN)lpbSaclPresent, pSacl, (PBOOLEAN)lpbSaclDefaulted));
 }	
 
 /**************************************************************************
  * SetSecurityDescriptorSacl			[NTDLL.488]
  */
-BOOL  WINAPI SetSecurityDescriptorSacl (
+BOOL WINAPI SetSecurityDescriptorSacl (
 	PSECURITY_DESCRIPTOR lpsd,
 	BOOL saclpresent,
 	PACL lpsacl,
@@ -496,11 +441,12 @@
  *   lpbuflen      []
  */
 BOOL WINAPI
-MakeSelfRelativeSD( PSECURITY_DESCRIPTOR lpabssecdesc,
-                    PSECURITY_DESCRIPTOR lpselfsecdesc, LPDWORD lpbuflen )
+MakeSelfRelativeSD(
+	IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
+	IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
+	IN OUT LPDWORD lpdwBufferLength)
 {
-	FIXME("(%p,%p,%p),stub!\n",lpabssecdesc,lpselfsecdesc,lpbuflen);
-	return TRUE;
+	CallWin32ToNt (RtlMakeSelfRelativeSD(pAbsoluteSecurityDescriptor,pSelfRelativeSecurityDescriptor, lpdwBufferLength));
 }
 
 /******************************************************************************
@@ -509,11 +455,24 @@
 
 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
 		 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
-{	FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor,pControl,lpdwRevision);
-	return 1;
+{
+	CallWin32ToNt (RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
 }		
 
 /*	##############################
+	######	ACL FUNCTIONS	######
+	##############################
+*/
+
+/*************************************************************************
+ * InitializeAcl [ADVAPI32.111]
+ */
+DWORD WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
+{
+	CallWin32ToNt (RtlCreateAcl(acl, size, rev));
+}
+
+/*	##############################
 	######	MISC FUNCTIONS	######
 	##############################
 */
@@ -536,7 +495,7 @@
 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, LPVOID lpLuid )
 {
     FIXME("(%s,%s,%p): stub\n",debugstr_w(lpSystemName), 
-          debugstr_w(lpName), lpLuid);
+        debugstr_w(lpName), lpLuid);
     return TRUE;
 }
 
@@ -548,7 +507,9 @@
 {
     LPWSTR lpSystemNameW = HEAP_strdupAtoW(GetProcessHeap(), 0, lpSystemName);
     LPWSTR lpNameW = HEAP_strdupAtoW(GetProcessHeap(), 0, lpName);
-    BOOL ret = LookupPrivilegeValueW( lpSystemNameW, lpNameW, lpLuid);
+    BOOL ret;
+
+    ret = LookupPrivilegeValueW( lpSystemNameW, lpNameW, lpLuid);
     HeapFree(GetProcessHeap(), 0, lpNameW);
     HeapFree(GetProcessHeap(), 0, lpSystemNameW);
     return ret;
@@ -600,14 +561,33 @@
  * LookupAccountSid32A [ADVAPI32.86]
  */
 BOOL WINAPI
-LookupAccountSidA( LPCSTR system, PSID sid, LPCSTR account,
-                     LPDWORD accountSize, LPCSTR domain, LPDWORD domainSize,
-                     PSID_NAME_USE name_use )
+LookupAccountSidA(
+	IN LPCSTR system,
+	IN PSID sid,
+	OUT LPSTR account,
+	IN OUT LPDWORD accountSize,
+	OUT LPSTR domain,
+	IN OUT LPDWORD domainSize,
+	OUT PSID_NAME_USE name_use )
 {
-	FIXME_(security)("(%s,%p,%p,%p,%p,%p,%p): stub\n",
-	      system,sid,account,accountSize,domain,domainSize,name_use);
-	SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-	return FALSE;
+	char * ac = "Administrator";
+	char * dm = "DOMAIN";
+	FIXME_(security)("(%s,sid=%p,%p,%p(%lu),%p,%p(%lu),%p): semi-stub\n",
+	      debugstr_a(system),sid,
+	      account,accountSize,accountSize?*accountSize:0,
+	      domain,domainSize,domainSize?*domainSize:0,
+	      name_use);
+
+	if (accountSize) *accountSize = strlen(ac)+1;
+	if (account && (*accountSize > strlen(ac)))
+	  strcpy(account, ac);
+
+	if (domainSize) *domainSize = strlen(dm)+1;
+	if (domain && (*domainSize > strlen(dm)))
+	  strcpy(domain,dm);
+
+	if (name_use) *name_use = SidTypeUser;
+	return TRUE;
 }
 
 /******************************************************************************
@@ -623,14 +603,33 @@
  *   name_use    []
  */
 BOOL WINAPI
-LookupAccountSidW( LPCWSTR system, PSID sid, LPCWSTR account, 
-                     LPDWORD accountSize, LPCWSTR domain, LPDWORD domainSize,
-                     PSID_NAME_USE name_use )
+LookupAccountSidW(
+	IN LPCWSTR system,
+	IN PSID sid,
+	OUT LPWSTR account,
+	IN OUT LPDWORD accountSize,
+	OUT LPWSTR domain,
+	IN OUT LPDWORD domainSize,
+	OUT PSID_NAME_USE name_use )
 {
-	FIXME_(security)("(%p,%p,%p,%p,%p,%p,%p): stub\n",
-	      system,sid,account,accountSize,domain,domainSize,name_use);
-	SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-	return FALSE;
+	char * ac = "Administrator";
+	char * dm = "DOMAIN";
+	FIXME_(security)("(%s,sid=%p,%p,%p(%lu),%p,%p(%lu),%p): semi-stub\n",
+	      debugstr_w(system),sid,
+	      account,accountSize,accountSize?*accountSize:0,
+	      domain,domainSize,domainSize?*domainSize:0,
+	      name_use);
+
+	if (accountSize) *accountSize = strlen(ac)+1;
+	if (account && (*accountSize > strlen(ac)))
+	  lstrcpyAtoW(account, ac);
+
+	if (domainSize) *domainSize = strlen(dm)+1;
+	if (domain && (*domainSize > strlen(dm)))
+	  lstrcpyAtoW(domain,dm);
+
+	if (name_use) *name_use = SidTypeUser;
+	return TRUE;
 }
 
 /******************************************************************************
@@ -703,37 +702,121 @@
  *   x4 []
  */
 NTSTATUS WINAPI
-LsaOpenPolicy(PLSA_UNICODE_STRING SystemName,
-	      PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
-	      ACCESS_MASK DesiredAccess,
-	      PLSA_HANDLE PolicyHandle)
+LsaOpenPolicy(
+	IN PLSA_UNICODE_STRING SystemName,
+	IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
+	IN ACCESS_MASK DesiredAccess,
+	IN OUT PLSA_HANDLE PolicyHandle)
 {
-	FIXME("(%p,%p,0x%08lx,%p):stub\n",
-              SystemName, ObjectAttributes, DesiredAccess, PolicyHandle);
-	return 0xc0000000; /* generic error */
+	FIXME("(%s,%p,0x%08lx,%p):stub\n",
+              SystemName?debugstr_w(SystemName->Buffer):"null",
+	      ObjectAttributes, DesiredAccess, PolicyHandle);
+	dumpLsaAttributes(ObjectAttributes);
+	if(PolicyHandle) *PolicyHandle = (LSA_HANDLE)0xcafe;
+	return TRUE;
 }
 
 /******************************************************************************
  * LsaQueryInformationPolicy [ADVAPI32.242]
  */
 NTSTATUS WINAPI
-LsaQueryInformationPolicy( IN LSA_HANDLE PolicyHandle,
-                           IN POLICY_INFORMATION_CLASS InformationClass,
-                           OUT PVOID *Buffer)
+LsaQueryInformationPolicy( 
+	IN LSA_HANDLE PolicyHandle,
+        IN POLICY_INFORMATION_CLASS InformationClass,
+	OUT PVOID *Buffer)
 {
 	FIXME("(%p,0x%08x,%p):stub\n",
               PolicyHandle, InformationClass, Buffer);
-	return 0xc0000000; /* generic error */
+
+	if(!Buffer) return FALSE;
+	switch (InformationClass)
+	{
+	  case PolicyAuditEventsInformation: /* 2 */
+	    {
+	      PPOLICY_AUDIT_EVENTS_INFO p = HeapAlloc(SystemHeap, HEAP_ZERO_MEMORY, sizeof(POLICY_AUDIT_EVENTS_INFO));
+	      p->AuditingMode = FALSE; /* no auditing */
+	      *Buffer = p;
+	    }
+	    break;
+	  case PolicyPrimaryDomainInformation: /* 3 */
+	  case PolicyAccountDomainInformation: /* 5 */
+	    {
+	      struct di
+	      { POLICY_PRIMARY_DOMAIN_INFO ppdi;
+		SID sid;
+	      };
+	      SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
+		
+	      struct di * xdi = HeapAlloc(SystemHeap, HEAP_ZERO_MEMORY, sizeof(xdi));
+	      RtlInitUnicodeString(&(xdi->ppdi.Name), HEAP_strdupAtoW(GetProcessHeap(),0,"DOMAIN"));
+	      xdi->ppdi.Sid = &(xdi->sid);
+	      xdi->sid.Revision = SID_REVISION;
+	      xdi->sid.SubAuthorityCount = 1;
+	      xdi->sid.IdentifierAuthority = localSidAuthority;
+	      xdi->sid.SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
+	      *Buffer = xdi;
+	    }
+	    break;
+	  case 	PolicyAuditLogInformation:	
+	  case 	PolicyPdAccountInformation:	
+	  case 	PolicyLsaServerRoleInformation:
+	  case 	PolicyReplicaSourceInformation:
+	  case 	PolicyDefaultQuotaInformation:
+	  case 	PolicyModificationInformation:
+	  case 	PolicyAuditFullSetInformation:
+	  case 	PolicyAuditFullQueryInformation:
+	  case 	PolicyDnsDomainInformation:
+	    {
+	      FIXME("category not implemented\n");
+	      return FALSE;
+	    }
+	}
+	return TRUE; 
 }			  
 
 /******************************************************************************
+ * LsaLookupSids [ADVAPI32.240]
+ */
+typedef struct
+{
+	SID_NAME_USE Use;
+	LSA_UNICODE_STRING Name;
+	LONG DomainIndex;
+} LSA_TRANSLATED_NAME, *PLSA_TRANSLATED_NAME;
+
+typedef struct 
+{
+	LSA_UNICODE_STRING Name;
+	PSID Sid;
+} LSA_TRUST_INFORMATION, *PLSA_TRUST_INFORMATION;
+
+typedef struct 
+{
+	ULONG Entries;
+	PLSA_TRUST_INFORMATION Domains;
+} LSA_REFERENCED_DOMAIN_LIST, *PLSA_REFERENCED_DOMAIN_LIST;
+
+NTSTATUS WINAPI
+LsaLookupSids(
+	IN LSA_HANDLE PolicyHandle,
+	IN ULONG Count,
+	IN PSID *Sids,
+	OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
+	OUT PLSA_TRANSLATED_NAME *Names )
+{
+	FIXME("%p %lu %p %p %p\n",
+	  PolicyHandle, Count, Sids, ReferencedDomains, Names);
+	return FALSE;
+}
+
+/******************************************************************************
  * LsaFreeMemory [ADVAPI32.241]
  */
 NTSTATUS WINAPI
 LsaFreeMemory(IN PVOID Buffer)
 {
-	FIXME("(%p):stub\n",Buffer);
-	return 0xc0000000;
+	TRACE("(%p)\n",Buffer);
+	return HeapFree(SystemHeap, 0, Buffer);
 }
 /******************************************************************************
  * LsaClose [ADVAPI32.243]
@@ -776,44 +859,37 @@
 BOOL WINAPI
 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
 {
-    FIXME("(%08x), stub\n", ImpersonationLevel);
-    return TRUE;
+	return RtlImpersonateSelf(ImpersonationLevel);
 }
 
 /******************************************************************************
  * AccessCheck32 [ADVAPI32.71]
+ *
+ * FIXME check cast LPBOOL to PBOOLEAN
  */
 BOOL WINAPI
-AccessCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken,
-	    DWORD DesiredAccess, PGENERIC_MAPPING GenericMapping, PPRIVILEGE_SET PrivilegeSet,
-	    LPDWORD PrivilegeSetLength, LPDWORD GrantedAccess, LPBOOL AccessStatus)
+AccessCheck(
+	PSECURITY_DESCRIPTOR SecurityDescriptor,
+	HANDLE ClientToken,
+	DWORD DesiredAccess,
+	PGENERIC_MAPPING GenericMapping,
+	PPRIVILEGE_SET PrivilegeSet,
+	LPDWORD PrivilegeSetLength,
+	LPDWORD GrantedAccess,
+	LPBOOL AccessStatus)
 {
-    FIXME("(%p, %04x, %08lx, %p, %p, %p, %p, %p), stub\n",
-          pSecurityDescriptor, ClientToken, DesiredAccess, GenericMapping, 
-          PrivilegeSet, PrivilegeSetLength, GrantedAccess, AccessStatus);
-    *AccessStatus = TRUE;
-    return TRUE;
+	CallWin32ToNt (NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
+	  GenericMapping, PrivilegeSet, PrivilegeSetLength, GrantedAccess, (PBOOLEAN)AccessStatus));
 }
 
 /*************************************************************************
- * SetThreadToken [ADVAPI32.231]
- *
- * Assigns an "impersonation token" to a thread so it can assume the
- * security privledges of another thread or process.  Can also remove
- * a previously assigned token.  Only supported on NT - it's a stub 
- * exactly like this one on Win9X.
- *
+ * SetKernelObjectSecurity [ADVAPI32.223]
  */
-
-BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
+BOOL WINAPI SetKernelObjectSecurity (
+	IN HANDLE Handle,
+	IN SECURITY_INFORMATION SecurityInformation,
+	IN PSECURITY_DESCRIPTOR SecurityDescriptor )
 {
-    FIXME("(%p, %x): stub\n", thread, token);
-
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-
-    return FALSE;
+	CallWin32ToNt (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
 }
 
-
-
-
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index f645687..e153b42 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -10,6 +10,7 @@
 C_SRCS = \
 	exception.c \
 	file.c \
+	misc.c \
 	nt.c \
 	om.c \
 	reg.c \
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 44a687c..5c5b992 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1,6 +1,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "debugtools.h"
+#include "ntdll_misc.h"
 
 #include "ntddk.h"
 
@@ -25,10 +26,10 @@
 	ULONG ShareAccess,
 	ULONG OpenOptions)
 {
-	FIXME("(%p,0x%08lx,%p(%s),%p,0x%08lx,0x%08lx) stub\n",
+	FIXME("(%p,0x%08lx,%p,%p,0x%08lx,0x%08lx) stub\n",
 	FileHandle, DesiredAccess, ObjectAttributes, 
-	ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL,
 	IoStatusBlock, ShareAccess, OpenOptions);
+	dump_ObjectAttributes (ObjectAttributes);
 	return 0;
 }
 
@@ -64,11 +65,11 @@
 	PVOID EaBuffer,
 	ULONG EaLength)  
 {
-	FIXME("(%p,0x%08lx,%p(%s),%p,%p,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx) stub\n",
+	FIXME("(%p,0x%08lx,%p,%p,%p,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx) stub\n",
 	FileHandle,DesiredAccess,ObjectAttributes,
-	ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL,
 	IoStatusBlock,AllocateSize,FileAttributes,
 	ShareAccess,CreateDisposition,CreateOptions,EaBuffer,EaLength);
+	dump_ObjectAttributes (ObjectAttributes);
 	return 0;
 }
 
@@ -210,6 +211,21 @@
 	FIXME("(0x%08x 0x%08x %p %p %p %p 0x%08lx 0x%08x 0x%08x %p 0x%08x\n",
 	FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation,
 	Length, FileInformationClass, ReturnSingleEntry, 
-	debugstr_w(FileName->Buffer),RestartScan);
+	debugstr_us(FileName),RestartScan);
 	return 0;
 }
+
+/******************************************************************************
+ *  NtQueryVolumeInformationFile		[NTDLL] 
+ */
+NTSTATUS WINAPI NtQueryVolumeInformationFile (
+	IN HANDLE FileHandle,
+	OUT PIO_STATUS_BLOCK IoStatusBlock,
+	OUT PVOID FSInformation,
+	IN ULONG Length,
+	IN FS_INFORMATION_CLASS FSInformationClass)
+{
+	TRACE("(0x%08x %p %p 0x%08lx 0x%08x) stub\n",
+	FileHandle, IoStatusBlock, FSInformation, Length, FSInformationClass);
+	return STATUS_SUCCESS;
+}
diff --git a/dlls/ntdll/misc.c b/dlls/ntdll/misc.c
new file mode 100644
index 0000000..6890c06
--- /dev/null
+++ b/dlls/ntdll/misc.c
@@ -0,0 +1,55 @@
+/*
+ * Helper functions for ntdll
+ */
+#include <time.h>
+
+#include "config.h"
+
+#include "debugstr.h"
+#include "debugtools.h"
+#include "ntdll_misc.h"
+
+DEFAULT_DEBUG_CHANNEL(ntdll)
+
+void dump_ObjectAttributes (POBJECT_ATTRIBUTES oa)
+{
+	if (oa)
+	  TRACE("%p:(name=%s, attr=0x%08lx, hRoot=0x%08x, sd=%p) \n",
+	    oa, debugstr_us(oa->ObjectName),
+	    oa->Attributes, oa->RootDirectory, oa->SecurityDescriptor);
+}
+
+void dump_AnsiString(PANSI_STRING as, BOOLEAN showstring)
+{
+	if (as)
+	{
+	  if (showstring)
+	    TRACE("%p %p(%s) (%u %u)\n", as, as->Buffer, debugstr_as(as), as->Length, as->MaximumLength);
+	  else
+	    TRACE("%p %p(<OUT>) (%u %u)\n", as, as->Buffer, as->Length, as->MaximumLength);
+	}
+}
+
+void dump_UnicodeString(PUNICODE_STRING us, BOOLEAN showstring)
+{
+	if (us)
+	{
+	  if (showstring)
+	    TRACE("%p %p(%s) (%u %u)\n", us, us->Buffer, debugstr_us(us), us->Length, us->MaximumLength);
+	  else
+	    TRACE("%p %p(<OUT>) (%u %u)\n", us, us->Buffer, us->Length, us->MaximumLength);
+	}
+}
+
+LPSTR debugstr_as (PANSI_STRING us)
+{
+	if (!us) return NULL;
+	return debugstr_an(us->Buffer, us->Length);
+}
+
+LPSTR debugstr_us (PUNICODE_STRING us)
+{
+	if (!us) return NULL;
+	return debugstr_wn(us->Buffer, us->Length);
+}
+
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 6f278a5..63fc4ec 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -15,6 +15,7 @@
 #include "debugtools.h"
 
 #include "ntddk.h"
+#include "ntdll_misc.h"
 
 DEFAULT_DEBUG_CHANNEL(ntdll)
 
@@ -31,10 +32,9 @@
 	IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
 	IN TIMER_TYPE TimerType)
 {
-	FIXME("(%p,0x%08lx,%p(%s),0x%08x) stub\n",
-	TimerHandle,DesiredAccess,ObjectAttributes,
-	ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL,
-	TimerType);
+	FIXME("(%p,0x%08lx,%p,0x%08x) stub\n",
+	TimerHandle,DesiredAccess,ObjectAttributes, TimerType);
+	dump_ObjectAttributes(ObjectAttributes);
 	return 0;
 }
 /**************************************************************************
@@ -192,8 +192,9 @@
         OUT PHANDLE NewToken)
 {
 	FIXME("(0x%08x,0x%08lx,%p,0x%08x,0x%08x,%p),stub!\n",
-	ExistingToken, DesiredAccess, ObjectAttributes, ImpersonationLevel,
-	TokenType, NewToken);
+	ExistingToken, DesiredAccess, ObjectAttributes,
+	ImpersonationLevel, TokenType, NewToken);
+	dump_ObjectAttributes(ObjectAttributes);
 	return 0;
 }
 
@@ -247,6 +248,11 @@
 /******************************************************************************
 *  NtQueryInformationToken		[NTDLL.156] 
 *
+* NOTES
+*  Buffer for TokenUser:
+*   0x00 TOKEN_USER the PSID field points to the SID
+*   0x08 SID
+*
 */
 NTSTATUS WINAPI NtQueryInformationToken(
 	HANDLE token,
@@ -263,7 +269,20 @@
 		*retlen = sizeof (TOKEN_GROUPS);
 		break;
 	  case TokenUser:	/* 1 */
-		*retlen = sizeof (TOKEN_USER);
+		{
+		  int len = sizeof (TOKEN_USER)+ sizeof(SID);
+		  *retlen = len;
+		  if ( len <= tokeninfolength)
+		  if( tokeninfo )
+		  {
+		    TOKEN_USER * tuser = tokeninfo;
+		    PSID sid = (PSID) &((LPBYTE)tokeninfo)[sizeof(TOKEN_USER)];
+		    SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
+		    RtlInitializeSid(sid, &localSidAuthority, 1);
+		    *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID;
+		    tuser->User.Sid = sid;
+		  }
+		}
 		break;
 	  case TokenPrivileges:
 		*retlen = sizeof (TOKEN_PRIVILEGES);
@@ -308,10 +327,10 @@
 	IN ULONG AllocationAttributes,
 	IN HANDLE FileHandle OPTIONAL)
 {
-	FIXME("(%p,0x%08lx,%p(%s),%p,0x%08lx,0x%08lx,0x%08x) stub\n",
-	SectionHandle,DesiredAccess,ObjectAttributes,
-	ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL,
+	FIXME("(%p,0x%08lx,%p,%p,0x%08lx,0x%08lx,0x%08x) stub\n",
+	SectionHandle,DesiredAccess, ObjectAttributes,
 	MaximumSize,SectionPageProtection,AllocationAttributes,FileHandle);
+	dump_ObjectAttributes(ObjectAttributes);
 	return 0;
 }
 
@@ -323,9 +342,9 @@
 	ACCESS_MASK DesiredAccess,
 	POBJECT_ATTRIBUTES ObjectAttributes)
 {
-	FIXME("(%p,0x%08lx,%p(%s)),stub!\n",
-	SectionHandle,DesiredAccess,ObjectAttributes,
-	ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL);
+	FIXME("(%p,0x%08lx,%p),stub!\n",
+	SectionHandle,DesiredAccess,ObjectAttributes);
+	dump_ObjectAttributes(ObjectAttributes);
 	return 0;
 }
 
@@ -549,6 +568,35 @@
 }
 
 /******************************************************************************
+ *  _alldiv					[NTDLL.937] 
+ * 
+ *
+ */
+long long WINAPI _alldiv(LARGE_INTEGER a,  LARGE_INTEGER b)
+{
+#if SIZEOF_LONG_LONG==8
+	return (*(long long*)&a / *(long long*)&b);
+#else
+	FIXME(ntdll,"stub\n");
+	retrun 0;
+#endif
+}
+/******************************************************************************
+ *  _allmul					[NTDLL.938] 
+ * 
+ *
+ */
+long long WINAPI _allmul(LARGE_INTEGER a,  LARGE_INTEGER b)
+{
+#if SIZEOF_LONG_LONG==8
+	return (*(long long*)&a * *(long long*)&b);
+#else
+	FIXME(ntdll,"stub\n");
+	retrun 0;
+#endif
+}
+
+/******************************************************************************
  *  NtPowerInformation				[NTDLL] 
  * 
  */
@@ -557,3 +605,20 @@
 	FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4,x5);
 	return 0;
 }
+
+/******************************************************************************
+ *  NtAllocateLocallyUniqueId
+ *
+ * FIXME: the server should do that
+ */
+NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID Luid)
+{
+	static LUID luid;
+
+	FIXME("%p (0x%08lx%08lx)\n", Luid, luid.DUMMYSTRUCTNAME.HighPart, luid.DUMMYSTRUCTNAME.LowPart);
+
+	luid.QuadPart++;
+	
+	Luid->QuadPart = luid.QuadPart;
+	return STATUS_SUCCESS;
+}
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index dac2506..58e013e 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -57,19 +57,19 @@
 @ stub NlsMbCodePageTag
 @ stub NlsMbOemCodePageTag
 @ stdcall NtAcceptConnectPort(long long long long long long) NtAcceptConnectPort
-@ stub NtAccessCheck
+@ stdcall NtAccessCheck(ptr long long ptr ptr ptr ptr ptr) NtAccessCheck
 @ stub NtAccessCheckAndAuditAlarm
 @ stub NtAdjustGroupsToken
 @ stdcall NtAdjustPrivilegesToken(long long long long long long) NtAdjustPrivilegesToken
 @ stub NtAlertResumeThread
 @ stub NtAlertThread
-@ stub NtAllocateLocallyUniqueId
+@ stdcall NtAllocateLocallyUniqueId(ptr) NtAllocateLocallyUniqueId
 @ stub NtAllocateUuids
 @ stub NtAllocateVirtualMemory
 @ stub NtCallbackReturn
 @ stub NtCancelIoFile
 @ stub NtCancelTimer
-@ stub NtClearEvent
+@ stdcall NtClearEvent(long) NtClearEvent
 @ stdcall NtClose(long) NtClose
 @ stub NtCloseObjectAuditAlarm
 @ stdcall NtCompleteConnectPort(long) NtCompleteConnectPort
@@ -150,13 +150,13 @@
 @ stub NtPrivilegeObjectAuditAlarm
 @ stub NtPrivilegedServiceAuditAlarm
 @ stub NtProtectVirtualMemory
-@ stub NtPulseEvent
+@ stdcall NtPulseEvent(long ptr) NtPulseEvent
 @ stub NtQueryAttributesFile
 @ stub NtQueryDefaultLocale
 @ stdcall NtQueryDirectoryFile(long long  ptr ptr ptr ptr long long long ptr long)NtQueryDirectoryFile
 @ stdcall NtQueryDirectoryObject(long long long long long long long) NtQueryDirectoryObject
 @ stub NtQueryEaFile
-@ stub NtQueryEvent
+@ stdcall NtQueryEvent(long long ptr long ptr) NtQueryEvent
 @ stdcall NtQueryInformationFile(long long long long long) NtQueryInformationFile
 @ stub NtQueryInformationPort
 @ stdcall NtQueryInformationProcess(long long long long long) NtQueryInformationProcess
@@ -179,7 +179,6 @@
 @ stdcall NtQueryTimerResolution(long long long) NtQueryTimerResolution
 @ stdcall NtQueryValueKey(long long long long long long) NtQueryValueKey
 @ stub NtQueryVirtualMemory
-@ stub NtQueryVolumeInformationFile
 @ stdcall NtRaiseException(ptr ptr long) NtRaiseException
 @ stub NtRaiseHardError
 @ stdcall NtReadFile(long long long long long long long long long) NtReadFile
@@ -197,7 +196,7 @@
 @ stub NtReplyWaitReplyPort
 @ stub NtRequestPort
 @ stdcall NtRequestWaitReplyPort(long long long) NtRequestWaitReplyPort
-@ stub NtResetEvent
+@ stdcall NtResetEvent(long ptr) NtResetEvent
 @ stdcall NtRestoreKey(long long long) NtRestoreKey
 @ stdcall NtResumeThread(long long) NtResumeThread
 @ stdcall NtSaveKey(long long) NtSaveKey
@@ -221,7 +220,7 @@
 @ stub NtSetLowEventPair
 @ stub NtSetLowWaitHighEventPair
 @ stub NtSetLowWaitHighThread
-@ stub NtSetSecurityObject
+@ stdcall NtSetSecurityObject(long long ptr) NtSetSecurityObject
 @ stub NtSetSystemEnvironmentValue
 @ stub NtSetSystemInformation
 @ stub NtSetSystemPowerState
@@ -290,7 +289,7 @@
 @ stub RtlCharToInteger
 @ stub RtlCheckRegistryKey
 @ stub RtlClearAllBits
-@ stub RtlClearBits
+@ stdcall RtlClearBits(long long long) RtlClearBits
 @ stub RtlCompactHeap
 @ stub RtlCompareMemory
 @ stub RtlCompareMemoryUlong
@@ -356,7 +355,7 @@
 @ stub RtlEqualComputerName
 @ stub RtlEqualDomainName
 @ stub RtlEqualLuid
-@ stub RtlEqualPrefixSid
+@ stdcall RtlEqualPrefixSid(ptr ptr) RtlEqualPrefixSid
 @ stdcall RtlEqualSid (long long) RtlEqualSid
 @ stub RtlEqualString
 @ stdcall RtlEqualUnicodeString(long long long) RtlEqualUnicodeString
@@ -368,7 +367,7 @@
 @ stub RtlExtendedMagicDivide
 @ stdcall RtlFillMemory(ptr long long) RtlFillMemory
 @ stub RtlFillMemoryUlong
-@ stub RtlFindClearBits
+@ stdcall RtlFindClearBits(long long long) RtlFindClearBits
 @ stub RtlFindClearBitsAndSet
 @ stub RtlFindLongestRunClear
 @ stub RtlFindLongestRunSet
@@ -376,7 +375,7 @@
 @ stub RtlFindSetBits
 @ stub RtlFindSetBitsAndClear
 @ stdcall RtlFirstFreeAce(ptr ptr) RtlFirstFreeAce
-@ stdcall RtlFormatCurrentUserKeyPath(wstr) RtlFormatCurrentUserKeyPath
+@ stdcall RtlFormatCurrentUserKeyPath(ptr) RtlFormatCurrentUserKeyPath
 @ stub RtlFormatMessage
 @ stdcall RtlFreeAnsiString(long) RtlFreeAnsiString
 @ stdcall RtlFreeHeap(long long long) RtlFreeHeap
@@ -387,7 +386,7 @@
 @ stdcall RtlGetAce(ptr long ptr) RtlGetAce
 @ stub RtlGetCallersAddress
 @ stub RtlGetCompressionWorkSpaceSize
-@ stub RtlGetControlSecurityDescriptor
+@ stdcall RtlGetControlSecurityDescriptor(ptr ptr ptr) RtlGetControlSecurityDescriptor
 @ stub RtlGetCurrentDirectory_U
 @ stdcall RtlGetDaclSecurityDescriptor(ptr ptr ptr ptr) RtlGetDaclSecurityDescriptor
 @ stub RtlGetElementGenericTable
@@ -400,19 +399,19 @@
 @ stub RtlGetProcessHeaps
 @ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr)RtlGetSaclSecurityDescriptor
 @ stub RtlGetUserInfoHeap
-@ stub RtlIdentifierAuthoritySid
+@ stdcall RtlIdentifierAuthoritySid(ptr) RtlIdentifierAuthoritySid
 @ stub RtlImageDirectoryEntryToData
 @ stdcall RtlImageNtHeader(long) RtlImageNtHeader
-@ stub RtlImpersonateSelf
+@ stdcall RtlImpersonateSelf(long) RtlImpersonateSelf
 @ stdcall RtlInitAnsiString(ptr str) RtlInitAnsiString
 @ stub RtlInitCodePageTable
 @ stub RtlInitNlsTables
 @ stdcall RtlInitString(ptr str) RtlInitString
 @ stdcall RtlInitUnicodeString(ptr wstr) RtlInitUnicodeString
-@ stub RtlInitializeBitMap
+@ stdcall RtlInitializeBitMap(long long long) RtlInitializeBitMap
 @ stub RtlInitializeContext
 @ stdcall RtlInitializeCriticalSection(ptr) InitializeCriticalSection
-@ stub RtlInitializeGenericTable
+@ stdcall RtlInitializeGenericTable() RtlInitializeGenericTable
 @ stub RtlInitializeRXact
 @ stdcall RtlInitializeResource(ptr) RtlInitializeResource
 @ stdcall RtlInitializeSid(ptr ptr long) RtlInitializeSid
@@ -438,7 +437,7 @@
 @ stub RtlLocalTimeToSystemTime
 @ stub RtlLockHeap
 @ stub RtlLookupElementGenericTable
-@ stub RtlMakeSelfRelativeSD
+@ stdcall RtlMakeSelfRelativeSD(ptr ptr ptr) RtlMakeSelfRelativeSD
 @ stub RtlMapGenericMask
 @ stdcall RtlMoveMemory(ptr ptr long) RtlMoveMemory
 @ stdcall RtlMultiByteToUnicodeN(ptr long ptr ptr long) RtlMultiByteToUnicodeN
@@ -457,7 +456,7 @@
 @ stdcall RtlOpenCurrentUser(long ptr) RtlOpenCurrentUser
 @ stub RtlPcToFileHeader
 @ stub RtlPrefixString
-@ stub RtlPrefixUnicodeString
+@ stdcall RtlPrefixUnicodeString(ptr ptr long) RtlPrefixUnicodeString
 @ stub RtlProtectHeap
 @ stdcall RtlQueryEnvironmentVariable_U(long long long) RtlQueryEnvironmentVariable_U
 @ stub RtlQueryInformationAcl
@@ -485,7 +484,7 @@
 @ stub RtlSecondsSince1980ToTime
 @ stub RtlSelfRelativeToAbsoluteSD
 @ stub RtlSetAllBits
-@ stub RtlSetBits
+@ stdcall RtlSetBits(long long long) RtlSetBits
 @ stub RtlSetCurrentDirectory_U
 @ stub RtlSetCurrentEnvironment
 @ stdcall RtlSetDaclSecurityDescriptor(ptr long ptr long) RtlSetDaclSecurityDescriptor
@@ -518,7 +517,7 @@
 @ stub RtlUnicodeStringToOemSize
 @ stdcall RtlUnicodeStringToOemString(ptr ptr long) RtlUnicodeStringToOemString
 @ stub RtlUnicodeToCustomCPN
-@ stub RtlUnicodeToMultiByteN
+@ stdcall RtlUnicodeToMultiByteN(ptr long ptr ptr long) RtlUnicodeToMultiByteN
 @ stub RtlUnicodeToMultiByteSize
 @ stdcall RtlUnicodeToOemN(ptr long ptr ptr long) RtlUnicodeToOemN
 @ stub RtlUniform
@@ -528,16 +527,16 @@
 @ stdcall RtlUpcaseUnicodeString(ptr ptr long) RtlUpcaseUnicodeString
 @ stub RtlUpcaseUnicodeStringToAnsiString
 @ stub RtlUpcaseUnicodeStringToCountedOemString
-@ stub RtlUpcaseUnicodeStringToOemString
+@ stdcall RtlUpcaseUnicodeStringToOemString(ptr ptr long) RtlUpcaseUnicodeStringToOemString
 @ stub RtlUpcaseUnicodeToCustomCPN
 @ stub RtlUpcaseUnicodeToMultiByteN
-@ stub RtlUpcaseUnicodeToOemN
+@ stdcall RtlUpcaseUnicodeToOemN(ptr long ptr ptr long) RtlUpcaseUnicodeToOemN
 @ stub RtlUpperChar
 @ stub RtlUpperString
 @ stub RtlUsageHeap
 @ stub RtlValidAcl
 @ stdcall RtlValidSecurityDescriptor(ptr) RtlValidSecurityDescriptor
-@ stub RtlValidSid
+@ stdcall RtlValidSid(ptr) RtlValidSid
 @ stub RtlValidateHeap
 @ stub RtlValidateProcessHeaps
 @ stub RtlWalkHeap
@@ -556,7 +555,7 @@
 @ stdcall RtlxAnsiStringToUnicodeSize(ptr) RtlxAnsiStringToUnicodeSize
 @ stdcall RtlxOemStringToUnicodeSize(ptr) RtlxOemStringToUnicodeSize
 @ stub RtlxUnicodeStringToAnsiSize
-@ stub RtlxUnicodeStringToOemSize
+@ stdcall RtlxUnicodeStringToOemSize(ptr) RtlxUnicodeStringToOemSize
 @ stub SaveEm87Context
 @ stdcall ZwAcceptConnectPort(long long long long long long) NtAcceptConnectPort
 @ stub ZwAccessCheck
@@ -956,8 +955,6 @@
 @ cdecl wcstol(wstr ptr long) CRTDLL_wcstol
 @ cdecl wcstombs(ptr ptr long) CRTDLL_wcstombs
 @ stub wcstoul
-
-# NT 4 additions
 @ stub NtAddAtom
 @ stub NtDeleteAtom
 @ stub NtFindAtom
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
new file mode 100644
index 0000000..134aadf
--- /dev/null
+++ b/dlls/ntdll/ntdll_misc.h
@@ -0,0 +1,14 @@
+#ifndef __WINE_NTDLL_MISC_H
+#define __WINE_NTDLL_MISC_H
+
+#include "ntdef.h"
+#include "winnt.h"
+
+/* debug helper */
+extern LPSTR debugstr_as (PANSI_STRING us);
+extern LPSTR debugstr_us (PUNICODE_STRING us);
+extern void dump_ObjectAttributes (POBJECT_ATTRIBUTES ObjectAttributes);
+extern void dump_AnsiString(PANSI_STRING as, BOOLEAN showstring);
+extern void dump_UnicodeString(PUNICODE_STRING us, BOOLEAN showstring);
+
+#endif
diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
index b85b801..81a0f02 100644
--- a/dlls/ntdll/om.c
+++ b/dlls/ntdll/om.c
@@ -7,6 +7,7 @@
 #include "debugtools.h"
 
 #include "ntddk.h"
+#include "ntdll_misc.h"
 
 DEFAULT_DEBUG_CHANNEL(ntdll)
 
@@ -34,11 +35,157 @@
 
 /******************************************************************************
  *  NtQuerySecurityObject	[NTDLL] 
+ *
+ * analogue to GetKernelObjectSecurity
+ *
+ * NOTES
+ *  only the lowest 4 bit of SecurityObjectInformationClass are used
+ *  0x7-0xf returns STATUS_ACCESS_DENIED (even running with system priviledges) 
+ *
+ * FIXME: we are constructing a fake sid 
+ *  (Administrators:Full, System:Full, Everyone:Read)
  */
-NTSTATUS WINAPI NtQuerySecurityObject(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5) 
+NTSTATUS WINAPI 
+NtQuerySecurityObject(
+	IN HANDLE Object,
+	IN SECURITY_INFORMATION RequestedInformation,
+	OUT PSECURITY_DESCRIPTOR pSecurityDesriptor,
+	IN ULONG Length,
+	OUT PULONG ResultLength)
 {
-	FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx) stub!\n",x1,x2,x3,x4,x5);
-	return 0;
+	static SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
+	static SID_IDENTIFIER_AUTHORITY worldSidAuthority = {SECURITY_WORLD_SID_AUTHORITY};
+	BYTE Buffer[256];
+	PISECURITY_DESCRIPTOR_RELATIVE psd = (PISECURITY_DESCRIPTOR_RELATIVE)Buffer;
+	UINT BufferIndex = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+	
+	FIXME("(0x%08x,0x%08lx,%p,0x%08lx,%p) stub!\n",
+	Object, RequestedInformation, pSecurityDesriptor, Length, ResultLength);
+
+	RequestedInformation &= 0x0000000f;
+
+	if (RequestedInformation & SACL_SECURITY_INFORMATION) return STATUS_ACCESS_DENIED;
+
+	ZeroMemory(Buffer, 256);
+	RtlCreateSecurityDescriptor((PSECURITY_DESCRIPTOR)psd, SECURITY_DESCRIPTOR_REVISION);
+	psd->Control = SE_SELF_RELATIVE | 
+	  ((RequestedInformation & DACL_SECURITY_INFORMATION) ? SE_DACL_PRESENT:0);
+
+	/* owner: administrator S-1-5-20-220*/
+	if (OWNER_SECURITY_INFORMATION & RequestedInformation)
+	{
+	  PSID psid = (PSID)&(Buffer[BufferIndex]);
+
+	  psd->Owner = BufferIndex;
+	  BufferIndex += RtlLengthRequiredSid(2);
+
+	  psid->Revision = SID_REVISION;
+	  psid->SubAuthorityCount = 2;
+	  psid->IdentifierAuthority = localSidAuthority;
+	  psid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID;
+	  psid->SubAuthority[1] = DOMAIN_ALIAS_RID_ADMINS;
+	}
+	
+	/* group: built in domain S-1-5-12 */
+	if (GROUP_SECURITY_INFORMATION & RequestedInformation)
+	{
+	  PSID psid = (PSID) &(Buffer[BufferIndex]);
+
+	  psd->Group = BufferIndex;
+	  BufferIndex += RtlLengthRequiredSid(1);
+
+	  psid->Revision = SID_REVISION;
+	  psid->SubAuthorityCount = 1;
+	  psid->IdentifierAuthority = localSidAuthority;
+	  psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
+	}
+
+	/* discretionary ACL */
+	if (DACL_SECURITY_INFORMATION & RequestedInformation)
+	{
+	  /* acl header */
+	  PACL pacl = (PACL)&(Buffer[BufferIndex]);
+	  PACCESS_ALLOWED_ACE pace;
+	  PSID psid;
+	  	  	  
+	  psd->Dacl = BufferIndex;
+
+	  pacl->AclRevision = MIN_ACL_REVISION;
+	  pacl->AceCount = 3;
+	  pacl->AclSize = BufferIndex; /* storing the start index temporary */
+
+	  BufferIndex += sizeof(ACL);
+	  
+	  /* ACE System - full access */
+	  pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]);
+	  BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
+
+	  pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
+	  pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
+	  pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1);
+	  pace->Mask = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER  | 0x3f;
+	  pace->SidStart = BufferIndex;
+
+	  /* SID S-1-5-12 (System) */
+	  psid = (PSID)&(Buffer[BufferIndex]);
+
+	  BufferIndex += RtlLengthRequiredSid(1);
+
+	  psid->Revision = SID_REVISION;
+	  psid->SubAuthorityCount = 1;
+	  psid->IdentifierAuthority = localSidAuthority;
+	  psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
+	  
+	  /* ACE Administrators - full access*/
+	  pace = (PACCESS_ALLOWED_ACE) &(Buffer[BufferIndex]);
+	  BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
+
+	  pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
+	  pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
+	  pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(2);
+	  pace->Mask = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER  | 0x3f;
+	  pace->SidStart = BufferIndex;
+
+	  /* S-1-5-12 (Administrators) */
+	  psid = (PSID)&(Buffer[BufferIndex]);
+
+	  BufferIndex += RtlLengthRequiredSid(2);
+
+	  psid->Revision = SID_REVISION;
+	  psid->SubAuthorityCount = 2;
+	  psid->IdentifierAuthority = localSidAuthority;
+	  psid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID;
+	  psid->SubAuthority[1] = DOMAIN_ALIAS_RID_ADMINS;
+	 
+	  /* ACE Everyone - read access */
+	  pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]);
+	  BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
+
+	  pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
+	  pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
+	  pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1);
+	  pace->Mask = READ_CONTROL| 0x19;
+	  pace->SidStart = BufferIndex;
+
+	  /* SID S-1-1-0 (Everyone) */
+	  psid = (PSID)&(Buffer[BufferIndex]);
+
+	  BufferIndex += RtlLengthRequiredSid(1);
+
+	  psid->Revision = SID_REVISION;
+	  psid->SubAuthorityCount = 1;
+	  psid->IdentifierAuthority = worldSidAuthority;
+	  psid->SubAuthority[0] = 0;
+
+	  /* calculate used bytes */
+	  pacl->AclSize = BufferIndex - pacl->AclSize;
+	}
+	*ResultLength = BufferIndex;
+	TRACE("len=%lu\n", *ResultLength);
+	if (Length < *ResultLength) return STATUS_BUFFER_TOO_SMALL;
+	memcpy(pSecurityDesriptor, Buffer, *ResultLength);
+
+	return STATUS_SUCCESS;
 }
 /******************************************************************************
  *  NtDuplicateObject		[NTDLL] 
@@ -68,8 +215,10 @@
 NTSTATUS WINAPI NtClose(
 	HANDLE Handle) 
 {
-	FIXME("(0x%08x),stub!\n",Handle);
-	return 1;
+	TRACE("(0x%08x)\n",Handle);
+	if (CloseHandle(Handle))
+	  return STATUS_SUCCESS;
+	return STATUS_UNSUCCESSFUL; /*fixme*/
 }
 
 /******************************************************************************
@@ -102,10 +251,10 @@
 	ACCESS_MASK DesiredAccess,
 	POBJECT_ATTRIBUTES ObjectAttributes)
 {
-    FIXME("(%p,0x%08lx,%p(%s)): stub\n", 
-    DirectoryHandle, DesiredAccess, ObjectAttributes,
-    ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL);
-    return 0;
+	FIXME("(%p,0x%08lx,%p): stub\n", 
+	DirectoryHandle, DesiredAccess, ObjectAttributes);
+	dump_ObjectAttributes(ObjectAttributes);
+	return 0;
 }
 
 /******************************************************************************
@@ -116,9 +265,9 @@
 	ACCESS_MASK DesiredAccess,
 	POBJECT_ATTRIBUTES ObjectAttributes) 
 {
-	FIXME("(%p,0x%08lx,%p(%s)),stub!\n",
-	DirectoryHandle,DesiredAccess,ObjectAttributes,
-	ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL);
+	FIXME("(%p,0x%08lx,%p),stub!\n",
+	DirectoryHandle,DesiredAccess,ObjectAttributes);
+	dump_ObjectAttributes(ObjectAttributes);
 	return 0;
 }
 
@@ -162,9 +311,9 @@
 	IN ACCESS_MASK DesiredAccess,
 	IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-	FIXME("(%p,0x%08lx,%p(%s)) stub\n",
-	LinkHandle, DesiredAccess, ObjectAttributes,
-	ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL);
+	FIXME("(%p,0x%08lx,%p) stub\n",
+	LinkHandle, DesiredAccess, ObjectAttributes);
+	dump_ObjectAttributes(ObjectAttributes);
 	return 0;
 }
 
@@ -177,10 +326,9 @@
 	IN POBJECT_ATTRIBUTES ObjectAttributes,
 	IN PUNICODE_STRING Name)
 {
-	FIXME("(%p,0x%08lx,%p(%s), %p) stub\n",
-	SymbolicLinkHandle, DesiredAccess, ObjectAttributes, 
-	ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL,
-	debugstr_w(Name->Buffer));
+	FIXME("(%p,0x%08lx,%p, %p) stub\n",
+	SymbolicLinkHandle, DesiredAccess, ObjectAttributes, debugstr_us(Name));
+	dump_ObjectAttributes(ObjectAttributes);
 	return 0;
 }
 
@@ -193,7 +341,7 @@
 	OUT PULONG ReturnedLength OPTIONAL)
 {
 	FIXME("(0x%08x,%p,%p) stub\n",
-	LinkHandle, debugstr_w(LinkTarget->Buffer), ReturnedLength);
+	LinkHandle, debugstr_us(LinkTarget), ReturnedLength);
 
 	return 0;
 }
diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c
index ae86486..3aa6287 100644
--- a/dlls/ntdll/reg.c
+++ b/dlls/ntdll/reg.c
@@ -1,15 +1,124 @@
 /*
  *	registry functions
+ *
+ * NOTES:
+ * 	HKEY_LOCAL_MACHINE	\\REGISTRY\\MACHINE
+ *	HKEY_USERS		\\REGISTRY\\USER
+ *	HKEY_CURRENT_CONFIG	\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\HARDWARE PROFILES\\CURRENT
+  *	HKEY_CLASSES		\\REGISTRY\\MACHINE\\SOFTWARE\\CLASSES
  */
 
 #include "debugtools.h"
 #include "winreg.h"
-
+#include "winerror.h"
+#include "file.h"
+#include "server.h"
 #include "ntddk.h"
+#include "crtdll.h"
+#include "ntdll_misc.h"
 
 DEFAULT_DEBUG_CHANNEL(ntdll)
 
 
+/* helper to make the server functions return STATUS_ codes */
+static NTSTATUS ErrorCodeToStatus (DWORD Error)
+{
+	TRACE("err=%lu\n", Error);
+	switch (Error)
+	{
+	  case NO_ERROR:			return STATUS_SUCCESS;
+
+	  case ERROR_INSUFFICIENT_BUFFER:	return STATUS_BUFFER_TOO_SMALL;
+	  case ERROR_FILE_NOT_FOUND:		return STATUS_OBJECT_NAME_NOT_FOUND;
+	  case ERROR_NO_MORE_ITEMS:		return STATUS_NO_MORE_ENTRIES;
+/*
+	return STATUS_INVALID_PARAMETER;
+	return STATUS_INVALID_HANDLE 
+	return STATUS_ACCESS_DENIED
+*/
+/*	  case ERROR_MORE_DATA:			return STATUS_BUFFER_OVERFLOW;
+	  case ERROR_KEY_DELETED:		return STATUS_KEY_DELETED;
+	  case ERROR_CHILD_MUST_BE_VOLATILE:	return STATUS_CHILD_MUST_BE_VOLATILE;
+	  case ERROR_ACCESS_DENIED:		return STATUS_ACCESS_DENIED;
+	  case ERROR_NOT_REGISTRY_FILE:		return STATUS_NOT_REGISTRY_FILE;
+*/
+	  default:
+	    FIXME("Error code %lu not implemented\n", Error);
+	}
+	return STATUS_UNSUCCESSFUL;
+}
+
+#define nt_server_call(kind) (ret=ErrorCodeToStatus(server_call_noerr(kind)))
+
+/* copy a key name into the request buffer */
+static inline NTSTATUS copy_nameU( LPWSTR Dest, PUNICODE_STRING Name, UINT Offset )
+{
+	if (Name->Buffer) 
+	{
+	  if ((Name->Length-Offset) > MAX_PATH) return STATUS_BUFFER_OVERFLOW;
+	  lstrcpyW( Dest, Name->Buffer+Offset );
+	}
+	else Dest[0] = 0;
+	return STATUS_SUCCESS;
+}
+
+/* translates predefined paths to HKEY_ constants */
+static BOOLEAN _NtKeyToWinKey(
+	IN POBJECT_ATTRIBUTES ObjectAttributes,
+	OUT UINT * Offset,	/* offset within ObjectName */
+	OUT HKEY * KeyHandle)	/* translated handle */
+{
+	static const WCHAR KeyPath_HKLM[] = {
+		'\\','R','E','G','I','S','T','R','Y',
+		'\\','M','A','C','H','I','N','E',0};
+	static const WCHAR KeyPath_HKU [] = {
+		'\\','R','E','G','I','S','T','R','Y',
+		'\\','U','S','E','R',0};
+	static const WCHAR KeyPath_HCC [] = {
+		'\\','R','E','G','I','S','T','R','Y',
+		'\\','M','A','C','H','I','N','E',
+		'\\','S','Y','S','T','E','M',
+		'\\','C','U','R','R','E','N','T','C','O','N','T','R','O','L','S','E','T',
+		'\\','H','A','R','D','W','A','R','E','P','R','O','F','I','L','E','S',
+		'\\','C','U','R','R','E','N','T',0};
+	static const WCHAR KeyPath_HCR [] = {
+		'\\','R','E','G','I','S','T','R','Y',
+		'\\','M','A','C','H','I','N','E',
+		'\\','S','O','F','T','W','A','R','E',
+		'\\','C','L','A','S','S','E','S',0};
+	int len;
+	PUNICODE_STRING ObjectName = ObjectAttributes->ObjectName;
+	
+	if((ObjectName->Length > (len=lstrlenW(KeyPath_HKLM)))
+	&& (0==CRTDLL_wcsncmp(ObjectName->Buffer,KeyPath_HKLM,len)))
+	{  *KeyHandle = HKEY_LOCAL_MACHINE;
+	}
+	else if((ObjectName->Length > (len=lstrlenW(KeyPath_HKU)))
+	&& (0==CRTDLL_wcsncmp(ObjectName->Buffer,KeyPath_HKU,len)))
+	{  *KeyHandle = HKEY_USERS;
+	}
+	else if((ObjectName->Length > (len=lstrlenW(KeyPath_HCR)))
+	&& (0==CRTDLL_wcsncmp(ObjectName->Buffer,KeyPath_HCR,len)))
+	{  *KeyHandle = HKEY_CLASSES_ROOT;
+	}
+	else if((ObjectName->Length > (len=lstrlenW(KeyPath_HCC)))
+	&& (0==CRTDLL_wcsncmp(ObjectName->Buffer,KeyPath_HCC,len)))
+	{  *KeyHandle = HKEY_CURRENT_CONFIG;
+	}
+	else
+	{
+	  *KeyHandle = ObjectAttributes->RootDirectory;
+	  *Offset = 0;
+	  return FALSE;
+	}
+
+	if (ObjectName->Buffer[len] == (WCHAR)'\\') len++;
+	*Offset = len;
+
+	TRACE("off=%u hkey=0x%08x\n", *Offset, *KeyHandle);
+	return TRUE;
+}
+
 /******************************************************************************
  * NtCreateKey [NTDLL]
  * ZwCreateKey
@@ -23,10 +132,81 @@
 	ULONG CreateOptions,
 	PULONG Disposition)
 {
-	FIXME("(%p,0x%08lx,%p (%s),0x%08lx, %p(%s),0x%08lx,%p),stub!\n",
-	KeyHandle, DesiredAccess, ObjectAttributes,debugstr_w(ObjectAttributes->ObjectName->Buffer),
-	TitleIndex, Class, debugstr_w(Class->Buffer), CreateOptions, Disposition);
-	return 0;
+	struct create_key_request *req = get_req_buffer();
+	UINT ObjectNameOffset;
+	HKEY RootDirectory;
+	NTSTATUS ret;
+
+	TRACE("(%p,0x%08lx,0x%08lx,%p(%s),0x%08lx,%p)\n",
+	KeyHandle, DesiredAccess, TitleIndex, Class, debugstr_us(Class), CreateOptions, Disposition);
+	dump_ObjectAttributes(ObjectAttributes);
+
+	if (!KeyHandle)
+	  return STATUS_INVALID_PARAMETER;
+
+	_NtKeyToWinKey(ObjectAttributes, &ObjectNameOffset, &RootDirectory);
+
+	req->parent  = RootDirectory;
+	req->access  = DesiredAccess;
+	req->options = CreateOptions;
+	req->modif   = time(NULL);
+
+	if (copy_nameU( req->name, ObjectAttributes->ObjectName, ObjectNameOffset ) != STATUS_SUCCESS) 
+	  return STATUS_INVALID_PARAMETER;
+
+	if (Class)
+	{
+	  int ClassLen = Class->Length+1;
+	  if ( ClassLen*sizeof(WCHAR) > server_remaining(req->class)) return STATUS_BUFFER_OVERFLOW;
+	  lstrcpynW( req->class, Class->Buffer, ClassLen);
+	}
+	else
+	  req->class[0] = 0x0000;
+
+	if (nt_server_call(REQ_CREATE_KEY) == STATUS_SUCCESS)
+	{
+	  *KeyHandle = req->hkey;
+	  if (Disposition) *Disposition = req->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
+	}
+	return ret;
+}
+
+/******************************************************************************
+ * NtOpenKey [NTDLL.129]
+ * ZwOpenKey
+ *   OUT	PHANDLE			KeyHandle (returns 0 when failure)
+ *   IN		ACCESS_MASK		DesiredAccess
+ *   IN		POBJECT_ATTRIBUTES 	ObjectAttributes 
+ */
+NTSTATUS WINAPI NtOpenKey(
+	PHANDLE KeyHandle,
+	ACCESS_MASK DesiredAccess,
+	POBJECT_ATTRIBUTES ObjectAttributes) 
+{
+	struct open_key_request *req = get_req_buffer();
+	UINT ObjectNameOffset;
+	HKEY RootDirectory;
+	NTSTATUS ret;
+
+	TRACE("(%p,0x%08lx)\n", KeyHandle, DesiredAccess);
+	dump_ObjectAttributes(ObjectAttributes);
+
+	if (!KeyHandle) return STATUS_INVALID_PARAMETER;
+	*KeyHandle = 0;
+
+	_NtKeyToWinKey(ObjectAttributes, &ObjectNameOffset, &RootDirectory);
+
+	req->parent = RootDirectory;
+	req->access = DesiredAccess;
+
+	if (copy_nameU( req->name, ObjectAttributes->ObjectName, ObjectNameOffset ) != STATUS_SUCCESS) 
+	  return STATUS_INVALID_PARAMETER;
+
+	if (nt_server_call(REQ_OPEN_KEY) == STATUS_SUCCESS)
+	{
+	  *KeyHandle = req->hkey;
+	}
+	return ret;
 }
 
 /******************************************************************************
@@ -37,7 +217,7 @@
 {
 	FIXME("(0x%08x) stub!\n",
 	KeyHandle);
-	return 1;
+	return STATUS_SUCCESS;
 }
 
 /******************************************************************************
@@ -49,13 +229,16 @@
 	IN PUNICODE_STRING ValueName)
 {
 	FIXME("(0x%08x,%p(%s)) stub!\n",
-	KeyHandle, ValueName,debugstr_w(ValueName->Buffer));
-	return 1;
-
+	KeyHandle, ValueName,debugstr_us(ValueName));
+	return STATUS_SUCCESS;
 }
+
 /******************************************************************************
  * NtEnumerateKey [NTDLL]
  * ZwEnumerateKey
+ *
+ * NOTES
+ *  the name copied into the buffer is NOT 0-terminated 
  */
 NTSTATUS WINAPI NtEnumerateKey(
 	HANDLE KeyHandle,
@@ -65,9 +248,156 @@
 	ULONG Length,
 	PULONG ResultLength)
 {
-	FIXME("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p) stub\n",
+	struct enum_key_request *req = get_req_buffer();
+	NTSTATUS ret;
+
+	TRACE("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p)\n",
 	KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
-	return 1;
+
+	req->hkey = KeyHandle;
+	req->index = Index;
+	if (nt_server_call(REQ_ENUM_KEY) != STATUS_SUCCESS) return ret;
+
+	switch (KeyInformationClass)
+	{
+	  case KeyBasicInformation:
+	    {
+	      PKEY_BASIC_INFORMATION kbi = KeyInformation;
+	      UINT NameLength = lstrlenW(req->name) * sizeof(WCHAR);
+	      *ResultLength = sizeof(KEY_BASIC_INFORMATION) - sizeof(WCHAR) + NameLength;
+	      if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
+
+	      DOSFS_UnixTimeToFileTime(req->modif, &kbi->LastWriteTime, 0);
+	      kbi->TitleIndex = 0;
+	      kbi->NameLength = NameLength;
+	      memcpy (kbi->Name, req->name, NameLength);
+	    }
+	    break;
+	  case KeyFullInformation:
+	    {
+	      PKEY_FULL_INFORMATION kfi = KeyInformation;
+	      kfi->ClassLength = lstrlenW(req->class) * sizeof(WCHAR);
+	      kfi->ClassOffset = (kfi->ClassLength) ?
+	        sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR) : 0xffffffff;
+	      *ResultLength = sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR) + kfi->ClassLength;
+	      if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
+
+	      DOSFS_UnixTimeToFileTime(req->modif, &kfi->LastWriteTime, 0);
+	      kfi->TitleIndex = 0;
+/*	      kfi->SubKeys = req->subkeys;
+	      kfi->MaxNameLength = req->max_subkey;
+	      kfi->MaxClassLength = req->max_class;
+	      kfi->Values = req->values;
+	      kfi->MaxValueNameLen = req->max_value;
+	      kfi->MaxValueDataLen = req->max_data;
+*/
+	      FIXME("incomplete\n");
+	      if (kfi->ClassLength) memcpy (kfi->Class, req->class, kfi->ClassLength);
+	    }
+	    break;
+	  case KeyNodeInformation:
+	    {
+	      PKEY_NODE_INFORMATION kni = KeyInformation;
+	      kni->ClassLength = lstrlenW(req->class) * sizeof(WCHAR);
+	      kni->NameLength = lstrlenW(req->name) * sizeof(WCHAR);
+	      kni->ClassOffset = (kni->ClassLength) ?
+	        sizeof(KEY_NODE_INFORMATION) - sizeof(WCHAR) + kni->NameLength : 0xffffffff;
+
+	      *ResultLength = sizeof(KEY_NODE_INFORMATION) - sizeof(WCHAR) + kni->NameLength + kni->ClassLength;
+	      if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
+
+	      DOSFS_UnixTimeToFileTime(req->modif, &kni->LastWriteTime, 0);
+	      kni->TitleIndex = 0;
+	      memcpy (kni->Name, req->name, kni->NameLength);
+	      if (kni->ClassLength) memcpy (KeyInformation+kni->ClassOffset, req->class, kni->ClassLength);
+	    }
+	    break;
+	  default:
+	    FIXME("KeyInformationClass not implemented\n");
+	    return STATUS_UNSUCCESSFUL;
+	}
+	TRACE("buf=%lu len=%lu\n", Length, *ResultLength);
+	return ret;
+}
+
+/******************************************************************************
+ * NtQueryKey [NTDLL]
+ * ZwQueryKey
+ */
+NTSTATUS WINAPI NtQueryKey(
+	HANDLE KeyHandle,
+	KEY_INFORMATION_CLASS KeyInformationClass,
+	PVOID KeyInformation,
+	ULONG Length,
+	PULONG ResultLength)
+{
+	struct query_key_info_request *req = get_req_buffer();
+	NTSTATUS ret;
+	
+	TRACE("(0x%08x,0x%08x,%p,0x%08lx,%p) stub\n",
+	KeyHandle, KeyInformationClass, KeyInformation, Length, ResultLength);
+	
+	req->hkey = KeyHandle;
+	if ((ret=nt_server_call(REQ_QUERY_KEY_INFO)) != STATUS_SUCCESS) return ret;
+	
+	switch (KeyInformationClass)
+	{
+	  case KeyBasicInformation:
+	    {
+	      PKEY_BASIC_INFORMATION kbi = KeyInformation;
+	      UINT NameLength = lstrlenW(req->name) * sizeof(WCHAR);
+	      *ResultLength = sizeof(KEY_BASIC_INFORMATION) - sizeof(WCHAR) + NameLength;
+	      if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
+
+	      DOSFS_UnixTimeToFileTime(req->modif, &kbi->LastWriteTime, 0);
+	      kbi->TitleIndex = 0;
+	      kbi->NameLength = NameLength;
+	      memcpy (kbi->Name, req->name, NameLength);
+	    }
+	    break;
+	  case KeyFullInformation:
+	    {
+	      PKEY_FULL_INFORMATION kfi = KeyInformation;
+	      kfi->ClassLength = lstrlenW(req->class) * sizeof(WCHAR);
+	      kfi->ClassOffset = (kfi->ClassLength) ?
+	        sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR) : 0xffffffff;
+
+	      *ResultLength = sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR) + kfi->ClassLength;
+	      if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
+
+	      DOSFS_UnixTimeToFileTime(req->modif, &kfi->LastWriteTime, 0);
+	      kfi->TitleIndex = 0;
+	      kfi->SubKeys = req->subkeys;
+	      kfi->MaxNameLen = req->max_subkey;
+	      kfi->MaxClassLen = req->max_class;
+	      kfi->Values = req->values;
+	      kfi->MaxValueNameLen = req->max_value;
+	      kfi->MaxValueDataLen = req->max_data;
+	      if(kfi->ClassLength) memcpy (KeyInformation+kfi->ClassOffset, req->class, kfi->ClassLength);
+	    }
+	    break;
+	  case KeyNodeInformation:
+	    {
+	      PKEY_NODE_INFORMATION kni = KeyInformation;
+	      kni->ClassLength = lstrlenW(req->class) * sizeof(WCHAR);
+	      kni->NameLength = lstrlenW(req->name) * sizeof(WCHAR);
+	      kni->ClassOffset = (kni->ClassLength) ?
+	        sizeof(KEY_NODE_INFORMATION) - sizeof(WCHAR) + kni->NameLength : 0xffffffff;
+
+	      *ResultLength = sizeof(KEY_NODE_INFORMATION) - sizeof(WCHAR) + kni->NameLength + kni->ClassLength;
+	      if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
+
+	      DOSFS_UnixTimeToFileTime(req->modif, &kni->LastWriteTime, 0);
+	      kni->TitleIndex = 0;
+	      memcpy (kni->Name, req->name, kni->NameLength);
+	      if(kni->ClassLength) memcpy (KeyInformation+kni->ClassOffset, req->class, kni->ClassLength);
+	    }
+	    break;
+	  default:
+	    FIXME("KeyInformationClass not implemented\n");
+	    return STATUS_UNSUCCESSFUL;
+	}
+	return ret;
 }
 
 /******************************************************************************
@@ -82,9 +412,71 @@
 	ULONG Length,
 	PULONG ResultLength)
 {
-	FIXME("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p) stub!\n",
+	struct enum_key_value_request *req = get_req_buffer();
+	UINT NameLength;
+	NTSTATUS ret;
+	
+	TRACE("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p)\n",
 	KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
-	return 1;
+
+	req->hkey = KeyHandle;
+	req->index = Index;
+	if (nt_server_call(REQ_ENUM_KEY_VALUE) != STATUS_SUCCESS) return ret;
+
+ 	switch (KeyInformationClass)
+	{
+	  case KeyBasicInformation:
+	    {
+	      PKEY_VALUE_BASIC_INFORMATION kbi = KeyInformation;
+	      
+	      NameLength = lstrlenW(req->name) * sizeof(WCHAR);
+	      *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) - sizeof(WCHAR) + NameLength;
+	      if (*ResultLength > Length) return STATUS_BUFFER_TOO_SMALL;
+
+	      kbi->TitleIndex = 0;
+	      kbi->Type = req->type;
+	      kbi->NameLength = NameLength;
+	      memcpy(kbi->Name, req->name, kbi->NameLength);
+	    }
+	    break;
+	  case KeyValueFullInformation:
+	    {
+	      PKEY_VALUE_FULL_INFORMATION kbi = KeyInformation;
+	      UINT DataOffset;
+
+	      NameLength = lstrlenW(req->name) * sizeof(WCHAR);
+	      DataOffset = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR) + NameLength;
+	      *ResultLength = DataOffset + req->len;
+
+	      if (*ResultLength > Length) return STATUS_BUFFER_TOO_SMALL;
+
+	      kbi->TitleIndex = 0;
+	      kbi->Type = req->type;
+	      kbi->DataOffset = DataOffset;
+	      kbi->DataLength = req->len;
+	      kbi->NameLength = NameLength;
+	      memcpy(kbi->Name, req->name, kbi->NameLength);
+	      memcpy(((LPBYTE)kbi) + DataOffset, req->data, req->len);
+	    }
+	    break;
+	  case KeyValuePartialInformation:
+	    {
+	      PKEY_VALUE_PARTIAL_INFORMATION kbi = KeyInformation;
+	      
+	      *ResultLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) - sizeof(WCHAR) + req->len;
+
+	      if (*ResultLength > Length) return STATUS_BUFFER_TOO_SMALL;
+
+	      kbi->TitleIndex = 0;
+	      kbi->Type = req->type;
+	      kbi->DataLength = req->len;
+	      memcpy(kbi->Data, req->data, req->len);
+	    }
+	    break;
+	  default:
+	    FIXME("not implemented\n");
+	}
+	return STATUS_SUCCESS;
 }
 
 /******************************************************************************
@@ -106,10 +498,9 @@
 	PHANDLE KeyHandle,
 	POBJECT_ATTRIBUTES ObjectAttributes)
 {
-	FIXME("(%p,%p (%s)),stub!\n",
-	KeyHandle, ObjectAttributes,debugstr_w(ObjectAttributes->ObjectName->Buffer));
-	return 0;
-
+	FIXME("(%p),stub!\n", KeyHandle);
+	dump_ObjectAttributes(ObjectAttributes);
+	return STATUS_SUCCESS;
 }
 
 /******************************************************************************
@@ -131,41 +522,7 @@
 	FIXME("(0x%08x,0x%08x,%p,%p,%p,0x%08lx, 0x%08x,%p,0x%08lx,0x%08x) stub!\n",
 	KeyHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, CompletionFilter,
 	Asynchroneous, ChangeBuffer, Length, WatchSubtree);
-	return 0;
-}
-
-
-/******************************************************************************
- * NtOpenKey [NTDLL.129]
- * ZwOpenKey
- *   OUT	PHANDLE			KeyHandle,
- *   IN		ACCESS_MASK		DesiredAccess,
- *   IN		POBJECT_ATTRIBUTES 	ObjectAttributes 
- */
-NTSTATUS WINAPI NtOpenKey(
-	PHANDLE KeyHandle,
-	ACCESS_MASK DesiredAccess,
-	POBJECT_ATTRIBUTES ObjectAttributes) 
-{
-	FIXME("(%p,0x%08lx,%p (%s)),stub!\n",
-	KeyHandle, DesiredAccess, ObjectAttributes,debugstr_w(ObjectAttributes->ObjectName->Buffer));
-	return 0;
-}
-
-/******************************************************************************
- * NtQueryKey [NTDLL]
- * ZwQueryKey
- */
-NTSTATUS WINAPI NtQueryKey(
-	HANDLE KeyHandle,
-	KEY_INFORMATION_CLASS KeyInformationClass,
-	PVOID KeyInformation,
-	ULONG Length,
-	PULONG ResultLength)
-{
-	FIXME("(0x%08x,0x%08x,%p,0x%08lx,%p) stub\n",
-	KeyHandle, KeyInformationClass, KeyInformation, Length, ResultLength);
-	return 0;
+	return STATUS_SUCCESS;
 }
 
 /******************************************************************************
@@ -184,24 +541,80 @@
 	FIXME("(0x%08x,%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
 	KeyHandle, ListOfValuesToQuery, NumberOfItems, MultipleValueInformation,
 	Length,ReturnLength);
-	return 0;
+	return STATUS_SUCCESS;
 }
 
 /******************************************************************************
  * NtQueryValueKey [NTDLL]
  * ZwQueryValueKey
+ *
+ * NOTES
+ *  the name in the KeyValueInformation is never set
  */
 NTSTATUS WINAPI NtQueryValueKey(
-	HANDLE KeyHandle,
-	PUNICODE_STRING ValueName,
-	KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
-	PVOID KeyValueInformation,
-	ULONG Length,
-	PULONG ResultLength)
+	IN HANDLE KeyHandle,
+	IN PUNICODE_STRING ValueName,
+	IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
+	OUT PVOID KeyValueInformation,
+	IN ULONG Length,
+	OUT PULONG ResultLength)
 {
-	FIXME("(0x%08x,%p,0x%08x,%p,0x%08lx,%p) stub\n",
-	KeyHandle, ValueName, KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
-	return 0;
+	struct get_key_value_request *req = get_req_buffer();
+	NTSTATUS ret;
+
+	TRACE("(0x%08x,%s,0x%08x,%p,0x%08lx,%p)\n",
+	KeyHandle, debugstr_us(ValueName), KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
+
+	req->hkey = KeyHandle;
+	if (copy_nameU(req->name, ValueName, 0) != STATUS_SUCCESS) return STATUS_BUFFER_OVERFLOW;
+	if (nt_server_call(REQ_GET_KEY_VALUE) != STATUS_SUCCESS) return ret;
+
+	switch(KeyValueInformationClass)
+	{
+	  case KeyValueBasicInformation:
+	    {
+	      PKEY_VALUE_BASIC_INFORMATION kbi = (PKEY_VALUE_BASIC_INFORMATION) KeyValueInformation;
+	      kbi->Type = req->type;
+
+	      *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION)-sizeof(WCHAR);
+	      if (Length <= *ResultLength) return STATUS_BUFFER_OVERFLOW;
+	      kbi->NameLength = 0;
+	    }  
+	    break;
+	  case KeyValueFullInformation:
+	    {
+	      PKEY_VALUE_FULL_INFORMATION  kfi = (PKEY_VALUE_FULL_INFORMATION) KeyValueInformation;
+	      ULONG DataOffset;
+	      kfi->Type = req->type;
+
+	      DataOffset = sizeof(KEY_VALUE_FULL_INFORMATION)-sizeof(WCHAR);
+	      *ResultLength = DataOffset + req->len;
+	      if (Length <= *ResultLength) return STATUS_BUFFER_OVERFLOW;
+
+	      kfi->NameLength = 0;
+	      kfi->DataOffset = DataOffset;
+	      kfi->DataLength = req->len;
+	      memcpy(KeyValueInformation+DataOffset, req->data, req->len);
+	    }  
+	    break;
+	  case KeyValuePartialInformation:
+	    {
+	      PKEY_VALUE_PARTIAL_INFORMATION kpi = (PKEY_VALUE_PARTIAL_INFORMATION) KeyValueInformation;
+	      kpi->Type = req->type;
+
+	      *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION)-sizeof(UCHAR)+req->len;
+	      if (Length <= *ResultLength) return STATUS_BUFFER_OVERFLOW;
+
+	      kpi->DataLength = req->len;
+	      memcpy(kpi->Data, req->data, req->len);
+	    }  
+	    break;
+	  default:
+	    FIXME("KeyValueInformationClass not implemented\n");
+	    return STATUS_UNSUCCESSFUL;
+	  
+	}
+	return ret;
 }
 
 /******************************************************************************
@@ -213,11 +626,10 @@
 	IN HANDLE Key,
 	IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
 {
-	FIXME("(%p(%s),0x%08x,%p (%s)),stub!\n",
-	ObjectAttributes,debugstr_w(ObjectAttributes->ObjectName->Buffer),Key,
-	ReplacedObjectAttributes,debugstr_w(ReplacedObjectAttributes->ObjectName->Buffer));
-	return 0;
-
+	FIXME("(0x%08x),stub!\n", Key);
+	dump_ObjectAttributes(ObjectAttributes);
+	dump_ObjectAttributes(ReplacedObjectAttributes);
+	return STATUS_SUCCESS;
 }
 /******************************************************************************
  * NtRestoreKey [NTDLL]
@@ -230,8 +642,7 @@
 {
 	FIXME("(0x%08x,0x%08x,0x%08lx) stub\n",
 	KeyHandle, FileHandle, RestoreFlags);
-	return 0;
-
+	return STATUS_SUCCESS;
 }
 /******************************************************************************
  * NtSaveKey [NTDLL]
@@ -243,7 +654,7 @@
 {
 	FIXME("(0x%08x,0x%08x) stub\n",
 	KeyHandle, FileHandle);
-	return 0;
+	return STATUS_SUCCESS;
 }
 /******************************************************************************
  * NtSetInformationKey [NTDLL]
@@ -257,7 +668,7 @@
 {
 	FIXME("(0x%08x,0x%08x,%p,0x%08lx) stub\n",
 	KeyHandle, KeyInformationClass, KeyInformation, KeyInformationLength);
-	return 0;
+	return STATUS_SUCCESS;
 }
 /******************************************************************************
  * NtSetValueKey [NTDLL]
@@ -272,8 +683,8 @@
 	ULONG DataSize)
 {
 	FIXME("(0x%08x,%p(%s), 0x%08lx, 0x%08lx, %p, 0x%08lx) stub!\n",
-	KeyHandle, ValueName,debugstr_w(ValueName->Buffer), TitleIndex, Type, Data, DataSize);
-	return 1;
+	KeyHandle, ValueName,debugstr_us(ValueName), TitleIndex, Type, Data, DataSize);
+	return STATUS_SUCCESS;
 
 }
 
@@ -286,5 +697,44 @@
 {
 	FIXME("(0x%08x) stub\n",
 	KeyHandle);
-	return 0;
+	return STATUS_SUCCESS;
+}
+
+/******************************************************************************
+ *  RtlFormatCurrentUserKeyPath		[NTDLL.371] 
+ */
+NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(
+	IN OUT PUNICODE_STRING KeyPath)
+{
+/*	LPSTR Path = "\\REGISTRY\\USER\\S-1-5-21-0000000000-000000000-0000000000-500";*/
+	LPSTR Path = "\\REGISTRY\\USER\\.DEFAULT";
+	ANSI_STRING AnsiPath;
+
+	FIXME("(%p) stub\n",KeyPath);
+	RtlInitAnsiString(&AnsiPath, Path);
+	return RtlAnsiStringToUnicodeString(KeyPath, &AnsiPath, TRUE);
+}
+
+/******************************************************************************
+ *  RtlOpenCurrentUser		[NTDLL] 
+ *
+ * if we return just HKEY_CURRENT_USER the advapi try's to find a remote
+ * registry (odd handle) and fails
+ *
+ */
+DWORD WINAPI RtlOpenCurrentUser(
+	IN ACCESS_MASK DesiredAccess,
+	OUT PHANDLE KeyHandle)	/* handle of HKEY_CURRENT_USER */
+{
+	OBJECT_ATTRIBUTES ObjectAttributes;
+	UNICODE_STRING ObjectName;
+	NTSTATUS ret;
+
+	TRACE("(0x%08lx, %p) stub\n",DesiredAccess, KeyHandle);
+
+	RtlFormatCurrentUserKeyPath(&ObjectName);
+	InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL);
+	ret = NtOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
+	RtlFreeUnicodeString(&ObjectName);
+	return ret;
 }
diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c
index f27d663..8cfe831 100644
--- a/dlls/ntdll/rtl.c
+++ b/dlls/ntdll/rtl.c
@@ -239,7 +239,7 @@
 	ULONG Flags,
 	ULONG Size)
 {
-	FIXME("(0x%08x, 0x%08lx, 0x%08lx) semi stub\n",
+	TRACE("(0x%08x, 0x%08lx, 0x%08lx) semi stub\n",
 	Heap, Flags, Size);
 	return HeapAlloc(Heap, Flags, Size);
 }
@@ -252,7 +252,7 @@
 	ULONG Flags,
 	PVOID Address)
 {
-	FIXME("(0x%08x, 0x%08lx, %p) semi stub\n",
+	TRACE("(0x%08x, 0x%08lx, %p) semi stub\n",
 	Heap, Flags, Address);
 	return HeapFree(Heap, Flags, Address);
 }
@@ -265,7 +265,7 @@
 BOOLEAN WINAPI RtlDestroyHeap(
 	HANDLE Heap)
 {
-	FIXME("(0x%08x) semi stub\n", Heap);
+	TRACE("(0x%08x) semi stub\n", Heap);
 	return HeapDestroy(Heap);
 }
 	
@@ -347,20 +347,72 @@
 /**************************************************************************
  *                 RtlNtStatusToDosError			[NTDLL.442]
  */
-DWORD WINAPI RtlNtStatusToDosError(DWORD error)
+DWORD WINAPI RtlNtStatusToDosError(DWORD Status)
 {
-	FIXME("(%lx): map STATUS_ to ERROR_\n",error);
-	switch (error)
-	{ case STATUS_SUCCESS:			return ERROR_SUCCESS;
-	  case STATUS_INVALID_PARAMETER:	return ERROR_BAD_ARGUMENTS;
-	  case STATUS_BUFFER_TOO_SMALL:		return ERROR_INSUFFICIENT_BUFFER;
-/*	  case STATUS_INVALID_SECURITY_DESCR:	return ERROR_INVALID_SECURITY_DESCR;*/
-	  case STATUS_NO_MEMORY:		return ERROR_NOT_ENOUGH_MEMORY;
-/*	  case STATUS_UNKNOWN_REVISION:
-	  case STATUS_BUFFER_OVERFLOW:*/
+	TRACE("(0x%08lx)\n",Status);
+
+	switch (Status & 0xC0000000)
+	{
+	  case 0x00000000:
+	    switch (Status)
+	    {
+/*00*/	      case STATUS_SUCCESS:			return ERROR_SUCCESS;
+	    }
+	    break;
+	  case 0x40000000:
+	    switch (Status)
+	    {
+	    }
+	    break;
+	  case 0x80000000:
+	    switch (Status)
+	    {
+	      case  STATUS_GUARD_PAGE_VIOLATION:	return STATUS_GUARD_PAGE_VIOLATION;
+	      case  STATUS_DATATYPE_MISALIGNMENT:	return ERROR_NOACCESS;
+	      case  STATUS_BREAKPOINT:			return STATUS_BREAKPOINT;
+	      case  STATUS_SINGLE_STEP:			return STATUS_SINGLE_STEP;
+	      case  STATUS_BUFFER_OVERFLOW:		return ERROR_MORE_DATA;
+	      case  STATUS_NO_MORE_FILES:		return ERROR_NO_MORE_FILES;
+/*	      case  STATUS_NO_INHERITANCE:		return ERROR_NO_INHERITANCE;*/
+	      case  STATUS_PARTIAL_COPY:		return ERROR_PARTIAL_COPY;
+/*	      case  STATUS_DEVICE_PAPER_EMPTY:		return ERROR_OUT_OF_PAPER;*/
+	      case  STATUS_DEVICE_POWERED_OFF:		return ERROR_NOT_READY;
+	      case  STATUS_DEVICE_OFF_LINE:		return ERROR_NOT_READY;
+	      case  STATUS_DEVICE_BUSY:			return ERROR_BUSY;
+	      case  STATUS_NO_MORE_EAS:			return ERROR_NO_MORE_ITEMS;
+	      case  STATUS_INVALID_EA_NAME:		return ERROR_INVALID_EA_NAME;
+	      case  STATUS_EA_LIST_INCONSISTENT:	return ERROR_EA_LIST_INCONSISTENT;
+	      case  STATUS_INVALID_EA_FLAG:		return ERROR_EA_LIST_INCONSISTENT;
+/*	      case  STATUS_VERIFY_REQUIRED:		return ERROR_MEDIA_CHANGED;*/
+	      case  STATUS_NO_MORE_ENTRIES:		return ERROR_NO_MORE_ITEMS;
+/*	      case  STATUS_FILEMARK_DETECTED:		return ERROR_FILEMARK_DETECTED;*/
+/*	      case  STATUS_MEDIA_CHANGED:		return ERROR_MEDIA_CHANGED;*/
+/*	      case  STATUS_BUS_RESET:			return ERROR_BUS_RESET;*/
+/*	      case  STATUS_END_OF_MEDIA:		return ERROR_END_OF_MEDIA;*/
+/*	      case  STATUS_BEGINNING_OF_MEDIA:		return ERROR_BEGINNING_OF_MEDIA;*/
+/*	      case  STATUS_SETMARK_DETECTED:		return ERROR_SETMARK_DETECTED;*/
+/*	      case  STATUS_NO_DATA_DETECTED:		return ERROR_NO_DATA_DETECTED;*/
+	      case  STATUS_ALREADY_DISCONNECTED:	return ERROR_ACTIVE_CONNECTIONS;
+	    }
+	    break;
+	  case 0xC0000000:
+	    switch (Status)
+	    {
+/*01*/	      case STATUS_UNSUCCESSFUL:			return ERROR_GEN_FAILURE;
+/*08*/	      case STATUS_NO_MEMORY:			return ERROR_NOT_ENOUGH_MEMORY;
+/*0d*/	      case STATUS_INVALID_PARAMETER:		return ERROR_INVALID_PARAMETER;
+/*22*/	      case STATUS_ACCESS_DENIED:		return ERROR_ACCESS_DENIED;
+/*23*/	      case STATUS_BUFFER_TOO_SMALL:		return ERROR_INSUFFICIENT_BUFFER;
+/*34*/	      case STATUS_OBJECT_NAME_NOT_FOUND:	return ERROR_FILE_NOT_FOUND;
+/*15c*/	      case STATUS_NOT_REGISTRY_FILE:		return ERROR_NOT_REGISTRY_FILE;
+/*17c*/	      case STATUS_KEY_DELETED:			return ERROR_KEY_DELETED;
+/*181*/	      case STATUS_CHILD_MUST_BE_VOLATILE:	return ERROR_CHILD_MUST_BE_VOLATILE;
+	    }
+	    break;
 	}
-	FIXME("unknown status (%lx)\n",error);
-	return ERROR_SUCCESS;
+	FIXME("unknown status (%lx)\n",Status);
+	return ERROR_MR_MID_NOT_FOUND; /*317*/
+	
 }
 
 /**************************************************************************
@@ -430,30 +482,6 @@
 #endif
 }
 
-/******************************************************************************
- *  RtlFormatCurrentUserKeyPath		[NTDLL.371] 
- */
-DWORD WINAPI RtlFormatCurrentUserKeyPath(PUNICODE_STRING String)
-{
-    FIXME("(%p): stub\n",String);
-    return 1;
-}
-
-/******************************************************************************
- *  RtlOpenCurrentUser		[NTDLL] 
- */
-DWORD WINAPI RtlOpenCurrentUser(DWORD x1, DWORD *x2)
-{
-/* Note: this is not the correct solution, 
- * But this works pretty good on wine and NT4.0 binaries
- */
-	if  ( x1 == 0x2000000 )  {
-		*x2 = HKEY_CURRENT_USER; 
-		return TRUE;
-	}
-		
-	return FALSE;
-}
 /**************************************************************************
  *                 RtlDosPathNameToNtPathName_U		[NTDLL.338]
  *
@@ -494,3 +522,52 @@
 	FIXME("(0x%08lx,%s,%p),stub!\n",x1,debugstr_w(key->Buffer),val);
 	return 0;
 }
+/******************************************************************************
+ *  RtlInitializeGenericTable		[NTDLL] 
+ */
+DWORD WINAPI RtlInitializeGenericTable(void)
+{
+	FIXME("\n");
+	return 0;
+}
+
+/******************************************************************************
+ *  RtlInitializeBitMap			[NTDLL] 
+ * 
+ */
+NTSTATUS WINAPI RtlInitializeBitMap(DWORD x1,DWORD x2,DWORD x3)
+{
+	FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
+	return 0;
+}
+
+/******************************************************************************
+ *  RtlSetBits				[NTDLL] 
+ * 
+ */
+NTSTATUS WINAPI RtlSetBits(DWORD x1,DWORD x2,DWORD x3)
+{
+	FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
+	return 0;
+}
+
+/******************************************************************************
+ *  RtlFindClearBits			[NTDLL] 
+ * 
+ */
+NTSTATUS WINAPI RtlFindClearBits(DWORD x1,DWORD x2,DWORD x3)
+{
+	FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
+	return 0;
+}
+
+/******************************************************************************
+ *  RtlClearBits			[NTDLL] 
+ * 
+ */
+NTSTATUS WINAPI RtlClearBits(DWORD x1,DWORD x2,DWORD x3)
+{
+	FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
+	return 0;
+}
+
diff --git a/dlls/ntdll/rtlstr.c b/dlls/ntdll/rtlstr.c
index 18710a7..3c19c8e 100644
--- a/dlls/ntdll/rtlstr.c
+++ b/dlls/ntdll/rtlstr.c
@@ -17,244 +17,520 @@
 #include "heap.h"
 #include "winnls.h"
 #include "debugtools.h"
-
+#include "ntdll_misc.h"
 #include "ntddk.h"
 
 DEFAULT_DEBUG_CHANNEL(ntdll)
-/*
- *	STRING FUNCTIONS
- */
+
+/*	STRING FUNCTIONS	*/
 
 /**************************************************************************
- *                 RtlAnsiStringToUnicodeString		[NTDLL.269]
- */
-DWORD /* NTSTATUS */ 
-WINAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING uni,PANSI_STRING ansi,BOOLEAN doalloc)
-{
-	DWORD	unilen = (ansi->Length+1)*sizeof(WCHAR);
-
-	if (unilen>0xFFFF)
-		return STATUS_INVALID_PARAMETER_2;
-	uni->Length = unilen;
-	if (doalloc) {
-		uni->MaximumLength = unilen;
-		uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen);
-		if (!uni->Buffer)
-			return STATUS_NO_MEMORY;
-	}
-	if (unilen>uni->MaximumLength)
-		return STATUS_BUFFER_OVERFLOW;
-	lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
-	return STATUS_SUCCESS;
-}
-
-/**************************************************************************
- *                 RtlOemStringToUnicodeString		[NTDLL.447]
- */
-DWORD /* NTSTATUS */ 
-WINAPI RtlOemStringToUnicodeString(PUNICODE_STRING uni,PSTRING ansi,BOOLEAN doalloc)
-{
-	DWORD	unilen = (ansi->Length+1)*sizeof(WCHAR);
-
-	if (unilen>0xFFFF)
-		return STATUS_INVALID_PARAMETER_2;
-	uni->Length = unilen;
-	if (doalloc) {
-		uni->MaximumLength = unilen;
-		uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen);
-		if (!uni->Buffer)
-			return STATUS_NO_MEMORY;
-	}
-	if (unilen>uni->MaximumLength)
-		return STATUS_BUFFER_OVERFLOW;
-	lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
-	return STATUS_SUCCESS;
-}
-/**************************************************************************
- *                 RtlMultiByteToUnicodeN		[NTDLL.436]
- * FIXME: multibyte support
- */
-DWORD /* NTSTATUS */ 
-WINAPI RtlMultiByteToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
-{
-	DWORD	len;
-	LPWSTR	x;
-
-	len = oemlen;
-	if (unilen/2 < len)
-		len = unilen/2;
-	x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
-	lstrcpynAtoW(x,oemstr,len+1);
-	memcpy(unistr,x,len*2);
-	if (reslen) *reslen = len*2;
-	return 0;
-}
-
-/**************************************************************************
- *                 RtlOemToUnicodeN			[NTDLL.448]
- */
-DWORD /* NTSTATUS */ 
-WINAPI RtlOemToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
-{
-	DWORD	len;
-	LPWSTR	x;
-
-	len = oemlen;
-	if (unilen/2 < len)
-		len = unilen/2;
-	x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
-	lstrcpynAtoW(x,oemstr,len+1);
-	memcpy(unistr,x,len*2);
-	if (reslen) *reslen = len*2;
-	return 0;
-}
-
-/**************************************************************************
- *                 RtlInitAnsiString			[NTDLL.399]
- */
-VOID WINAPI RtlInitAnsiString(PANSI_STRING target,LPCSTR source)
-{
-	target->Length = target->MaximumLength = 0;
-	target->Buffer = (LPSTR)source;
-	if (!source)
-		return;
-	target->MaximumLength = lstrlenA(target->Buffer);
-	target->Length = target->MaximumLength+1;
-}
-/**************************************************************************
- *                 RtlInitString			[NTDLL.402]
+ *	RtlInitString
  */
 VOID WINAPI RtlInitString(PSTRING target,LPCSTR source)
 {
-	target->Length = target->MaximumLength = 0;
+	TRACE("%p %p(%s)\n", target, source, debugstr_a(source));
+
 	target->Buffer = (LPSTR)source;
-	if (!source)
-		return;
-	target->MaximumLength = lstrlenA(target->Buffer);
-	target->Length = target->MaximumLength+1;
+	if (source)
+	{
+	  target->Length = lstrlenA(source);
+	  target->MaximumLength = target->Length+1;
+	}
+	else
+	{
+	  target->Length = target->MaximumLength = 0;
+	}
+}
+
+
+
+/*	ANSI FUNCTIONS	*/
+
+/**************************************************************************
+ *	RtlInitAnsiString
+ */
+VOID WINAPI RtlInitAnsiString(
+	PANSI_STRING target,
+	LPCSTR source)
+{
+	TRACE("%p %p(%s)\n", target, source, debugstr_a(source));
+
+	target->Buffer = (LPSTR)source;
+	if (source)
+	{
+	  target->Length = lstrlenA(source);
+	  target->MaximumLength = target->Length+1;
+	}
+	else
+	{
+	  target->Length = target->MaximumLength = 0;
+	}
 }
 
 /**************************************************************************
- *                 RtlInitUnicodeString			[NTDLL.403]
+ *	RtlFreeAnsiString
  */
-VOID WINAPI RtlInitUnicodeString(PUNICODE_STRING target,LPCWSTR source)
+VOID WINAPI RtlFreeAnsiString(
+	PANSI_STRING AnsiString)
+{
+	TRACE("%p\n", AnsiString);
+	dump_AnsiString(AnsiString, TRUE);
+
+	if( AnsiString->Buffer )
+	  HeapFree( GetProcessHeap(),0,AnsiString->Buffer );
+}
+
+
+
+/*	UNICODE FUNCTIONS	*/
+
+/**************************************************************************
+ *	RtlInitUnicodeString			[NTDLL.403]
+ */
+VOID WINAPI RtlInitUnicodeString(
+	PUNICODE_STRING target,
+	LPCWSTR source)
 {
 	TRACE("%p %p(%s)\n", target, source, debugstr_w(source));
 	
-	target->Length = target->MaximumLength = 0;
 	target->Buffer = (LPWSTR)source;
-	if (!source)
-		return;
-	target->MaximumLength = lstrlenW(target->Buffer)*2;
-	target->Length = target->MaximumLength+2;
-}
-
-/**************************************************************************
- *                 RtlFreeUnicodeString			[NTDLL.377]
- */
-VOID WINAPI RtlFreeUnicodeString(PUNICODE_STRING str)
-{
-	if (str->Buffer)
-		HeapFree(GetProcessHeap(),0,str->Buffer);
-}
-
-/**************************************************************************
- * RtlFreeAnsiString [NTDLL.373]
- */
-VOID WINAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
-{
-    if( AnsiString->Buffer )
-        HeapFree( GetProcessHeap(),0,AnsiString->Buffer );
-}
-
-
-/**************************************************************************
- *                 RtlUnicodeToOemN			[NTDLL.515]
- */
-DWORD /* NTSTATUS */ 
-WINAPI RtlUnicodeToOemN(LPSTR oemstr,DWORD oemlen,LPDWORD reslen,LPWSTR unistr,DWORD unilen)
-{
-	DWORD	len;
-	LPSTR	x;
-
-	len = oemlen;
-	if (unilen/2 < len)
-		len = unilen/2;
-	x=(LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+1);
-	lstrcpynWtoA(x,unistr,len+1);
-	memcpy(oemstr,x,len);
-	if (reslen) *reslen = len;
-	return 0;
-}
-
-/**************************************************************************
- *                 RtlUnicodeStringToOemString		[NTDLL.511]
- */
-DWORD /* NTSTATUS */ 
-WINAPI RtlUnicodeStringToOemString(PANSI_STRING oem,PUNICODE_STRING uni,BOOLEAN alloc)
-{
-	if (alloc) {
-		oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
-		oem->MaximumLength = uni->Length/2+1;
+	if (source)
+	{
+	  target->Length = lstrlenW(source)*2;
+	  target->MaximumLength = target->Length + 2;
 	}
-	oem->Length = uni->Length/2;
-	lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
-	return 0;
-}
-
-/**************************************************************************
- *                 RtlUnicodeStringToAnsiString		[NTDLL.507]
- */
-DWORD /* NTSTATUS */ 
-WINAPI RtlUnicodeStringToAnsiString(PANSI_STRING oem,PUNICODE_STRING uni,BOOLEAN alloc)
-{
-	if (alloc) {
-		oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
-		oem->MaximumLength = uni->Length/2+1;
+	else
+	{
+	  target->Length = target->MaximumLength = 0;
 	}
-	oem->Length = uni->Length/2;
-	lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
-	return 0;
 }
 
 /**************************************************************************
- *                 RtlEqualUnicodeString		[NTDLL]
+ *	RtlFreeUnicodeString			[NTDLL.377]
  */
-DWORD WINAPI RtlEqualUnicodeString(PUNICODE_STRING s1,PUNICODE_STRING s2,DWORD x) {
-	FIXME("(%s,%s,%ld),stub!\n",debugstr_w(s1->Buffer),debugstr_w(s2->Buffer),x);
-	return 0;
-	if (s1->Length != s2->Length)
-		return 1;
-	return !CRTDLL_wcsncmp(s1->Buffer,s2->Buffer,s1->Length/2);
-}
-
-/**************************************************************************
- *                 RtlUpcaseUnicodeString		[NTDLL.520]
- */
-DWORD WINAPI RtlUpcaseUnicodeString(PUNICODE_STRING dest,PUNICODE_STRING src,BOOLEAN doalloc)
+VOID WINAPI RtlFreeUnicodeString(
+	PUNICODE_STRING UnicodeString)
 {
-	LPWSTR	s,t;
-	DWORD	i,len;
+	TRACE("%p\n", UnicodeString);
+	dump_UnicodeString(UnicodeString, TRUE);
 
-	len = src->Length;
-	if (doalloc) {
-		dest->MaximumLength = len; 
-		dest->Buffer = (LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len);
-		if (!dest->Buffer)
-			return STATUS_NO_MEMORY;
+	if (UnicodeString->Buffer)
+	  HeapFree(GetProcessHeap(),0,UnicodeString->Buffer);
+}
 
+/*
+	 COMPARE FUNCTIONS
+*/
+
+/**************************************************************************
+ *	RtlEqualUnicodeString
+ */
+BOOLEAN WINAPI RtlEqualUnicodeString(
+	IN PUNICODE_STRING s1,
+	IN PUNICODE_STRING s2,
+        IN BOOLEAN CaseInsensitive) 
+{
+	BOOLEAN ret;
+	TRACE("(%p,%p,%x)\n",s1,s2,CaseInsensitive);
+	dump_UnicodeString(s1, TRUE);
+	dump_UnicodeString(s2, TRUE);
+
+	if(!s1 || !s2 || !s1->Buffer || !s2->Buffer) return FALSE;
+	if (s1->Length != s2->Length) return FALSE;
+
+	if (CaseInsensitive)
+	  ret = !CRTDLL__wcsnicmp(s1->Buffer,s2->Buffer,s1->Length/sizeof(WCHAR));
+	else	
+	  ret = !CRTDLL_wcsncmp(s1->Buffer,s2->Buffer,s1->Length/sizeof(WCHAR));
+	return ret;
+}
+
+/******************************************************************************
+ *	RtlCompareUnicodeString
+ */
+LONG WINAPI RtlCompareUnicodeString(
+	PUNICODE_STRING s1,
+	PUNICODE_STRING s2,
+	BOOLEAN CaseInsensitive) 
+{
+	LONG ret;
+
+	TRACE("(%p,%p,%x)\n",s1,s2,CaseInsensitive);
+	dump_UnicodeString(s1, TRUE);
+	dump_UnicodeString(s2, TRUE);
+
+	if(!s1 || !s2 || !s1->Buffer || !s2->Buffer) return FALSE;
+	
+	if (s1->Length != s2->Length) return (s1->Length - s2->Length);
+
+	if (CaseInsensitive)
+	  ret = CRTDLL__wcsnicmp(s1->Buffer,s2->Buffer,s1->Length/sizeof(WCHAR));
+	else	
+	  ret = CRTDLL_wcsncmp(s1->Buffer,s2->Buffer,s1->Length/sizeof(WCHAR));
+	return ret;
+}
+
+/*
+	COPY BETWEEN ANSI_STRING or UNICODE_STRING
+	there is no parameter checking, it just crashes
+*/
+
+/**************************************************************************
+ *	RtlAnsiStringToUnicodeString
+ *
+ * NOTES:
+ *  writes terminating 0
+ */
+NTSTATUS
+WINAPI RtlAnsiStringToUnicodeString(
+	PUNICODE_STRING uni,
+	PANSI_STRING ansi,
+	BOOLEAN doalloc)
+{
+	int len = ansi->Length * sizeof(WCHAR);
+
+	TRACE("%p %p %u\n",uni, ansi, doalloc);
+	dump_AnsiString(ansi, TRUE);
+	dump_UnicodeString(uni, FALSE);
+
+	if (len>0xfffe) return STATUS_INVALID_PARAMETER_2;
+	uni->Length = len;
+	if (doalloc) 
+	{
+	  uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->MaximumLength);
+	  if (!uni->Buffer) return STATUS_NO_MEMORY;
+	  uni->MaximumLength = len + sizeof(WCHAR);
 	}
-	if (dest->MaximumLength < len)
-		return STATUS_BUFFER_OVERFLOW;
-	s=dest->Buffer;t=src->Buffer;
-	/* len is in bytes */
-	for (i=0;i<len/2;i++)
-		s[i] = towupper(t[i]);
+	else if (len+sizeof(WCHAR) > uni->MaximumLength)
+	{
+	  return STATUS_BUFFER_OVERFLOW;
+	}
+	lstrcpynAtoW(uni->Buffer,ansi->Buffer,ansi->Length+1);
 	return STATUS_SUCCESS;
 }
 
 /**************************************************************************
- *                 RtlxOemStringToUnicodeSize		[NTDLL.549]
+ *	RtlUpcaseUnicodeString
+ *
+ * NOTES:
+ *  destination string is never 0-terminated because dest can be equal to src
+ *  and src might be not 0-terminated
+ *  dest.Length only set when success
+ */
+DWORD WINAPI RtlUpcaseUnicodeString(
+	PUNICODE_STRING dest,
+	PUNICODE_STRING src,
+	BOOLEAN doalloc)
+{
+	int i, len = src->Length;
+
+	TRACE("(%p,%p,%x)\n",dest, src, doalloc);
+	dump_UnicodeString(dest, FALSE);
+	dump_UnicodeString(src, TRUE);
+
+	if (doalloc)
+	{
+	  dest->Buffer = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
+	  if (!dest->Buffer) return STATUS_NO_MEMORY;
+	  dest->MaximumLength = len; 
+	}
+	else if (len > dest->MaximumLength)
+	{
+	  return STATUS_BUFFER_OVERFLOW;
+	}
+
+	for (i=0; i < len/sizeof(WCHAR); i++)
+	{
+	  dest->Buffer[i] = towupper(src->Buffer[i]);
+	}
+	dest->Length = len;
+	return STATUS_SUCCESS;
+}
+
+/**************************************************************************
+ *	RtlOemStringToUnicodeString
+ *
+ * NOTES
+ *  writes terminating 0
+ *  buffer must be bigger than (ansi->Length+1)*2
+ *  if astr.Length > 0x7ffe it returns STATUS_INVALID_PARAMETER_2
+ *
+ * FIXME
+ *  OEM to unicode
+ */
+NTSTATUS
+WINAPI RtlOemStringToUnicodeString(
+	PUNICODE_STRING uni,
+	PSTRING ansi,
+	BOOLEAN doalloc)
+{
+	int len = ansi->Length * sizeof(WCHAR);
+
+	if (len > 0xfffe) return STATUS_INVALID_PARAMETER_2;
+
+	uni->Length = len;
+	if (doalloc) 
+	{
+	  uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, len + sizeof(WCHAR));
+	  if (!uni->Buffer) return STATUS_NO_MEMORY;
+	  uni->MaximumLength = len + sizeof(WCHAR);
+	}
+	else if (len+1 > uni->MaximumLength )
+	{
+	  return STATUS_BUFFER_OVERFLOW;
+	}
+	lstrcpynAtoW(uni->Buffer,ansi->Buffer,ansi->Length+1);
+	return STATUS_SUCCESS;
+}
+
+/**************************************************************************
+ *	RtlUnicodeStringToOemString
+ *
+ * NOTES
+ *   allocates uni->Length+1
+ *   writes terminating 0
+ */
+NTSTATUS
+WINAPI RtlUnicodeStringToOemString(
+	PANSI_STRING oem,
+	PUNICODE_STRING uni,
+	BOOLEAN doalloc)
+{
+	int len = uni->Length/sizeof(WCHAR);
+
+	TRACE("%p %s %i\n", oem, debugstr_us(uni), doalloc);
+
+	oem->Length = len;
+	if (doalloc)
+	{
+	  oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len+1);
+	  if (! oem->Buffer) return STATUS_NO_MEMORY;
+	  oem->MaximumLength = len + 1;
+	}
+	else if (oem->MaximumLength <= len)
+	{
+	  return STATUS_BUFFER_OVERFLOW;
+	}
+	lstrcpynWtoA(oem->Buffer, uni->Buffer, len+1);
+	return STATUS_SUCCESS;
+}
+
+/**************************************************************************
+ *	RtlUpcaseUnicodeStringToOemString
+ *
+ * NOTES
+ *  writes terminating 0
+ */
+NTSTATUS
+WINAPI RtlUpcaseUnicodeStringToOemString(
+	PANSI_STRING oem,
+	PUNICODE_STRING uni,
+	BOOLEAN doalloc)
+{
+	int i, len = uni->Length/sizeof(WCHAR);
+
+	TRACE("%p %s %i\n", oem, debugstr_us(uni), doalloc);
+
+	oem->Length = len;
+	if (doalloc)
+	{
+	  oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len+1);
+	  if (! oem->Buffer) return STATUS_NO_MEMORY;
+	  oem->MaximumLength = len + 1;
+	}
+	else if (oem->MaximumLength <= len)
+	{
+	  return STATUS_BUFFER_OVERFLOW;
+	}
+
+	for (i=0; i < len; i++)
+	{
+	  oem->Buffer[i] = towupper((char)(uni->Buffer[i]));
+	}
+	oem->Buffer[i] = 0;
+	return STATUS_SUCCESS;
+}
+
+/**************************************************************************
+ *	RtlUnicodeStringToAnsiString
+ *
+ * NOTES
+ *  writes terminating 0
+ *  copys a part if the buffer is to small
+ */
+NTSTATUS
+WINAPI RtlUnicodeStringToAnsiString(
+	PANSI_STRING ansi,
+	PUNICODE_STRING uni,
+	BOOLEAN doalloc)
+{
+	int len = uni->Length/sizeof(WCHAR);
+	NTSTATUS ret = STATUS_SUCCESS;
+
+	TRACE("%p %s %i\n", ansi, debugstr_us(uni), doalloc);
+
+	ansi->Length = len;
+	if (doalloc)
+	{
+	  ansi->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len+1);
+	  if (! ansi->Buffer) return STATUS_NO_MEMORY;
+	  ansi->MaximumLength = len + 1;
+	}
+	else if (ansi->MaximumLength <= len)
+	{
+	  ansi->Length = ansi->MaximumLength - 1;
+	  ret = STATUS_BUFFER_OVERFLOW;
+	}
+	lstrcpynWtoA(ansi->Buffer, uni->Buffer, ansi->Length+1);
+	return ret;
+}
+
+/*
+	COPY BETWEEN ANSI/UNICODE_STRING AND MULTIBYTE STRINGS
+*/
+/**************************************************************************
+ *	RtlMultiByteToUnicodeN
+ *
+ * NOTES
+ *  dest can be equal to src
+ *  if unistr is to small a part is copyed
+ *
+ * FIXME
+ *  multibyte support
+ */
+NTSTATUS
+WINAPI RtlMultiByteToUnicodeN(
+	LPWSTR unistr,
+	DWORD unilen,
+	LPDWORD reslen,
+	LPSTR oemstr,
+	DWORD oemlen)
+{
+	UINT len;
+	int i;
+
+	TRACE("%p %lu, %p, %s, %lu\n", oemstr, oemlen, reslen, debugstr_w(unistr), unilen);
+
+	len = (unilen/sizeof(WCHAR) < oemlen) ? unilen/sizeof(WCHAR) : oemlen;
+
+	for (i = len-1; i>=0; i--)
+	  unistr[i] = (WCHAR)oemstr[i];
+
+	if (reslen) *reslen = len * 2;
+	return 0;
+}
+
+/**************************************************************************
+ *	RtlOemToUnicodeN
+ */
+NTSTATUS
+WINAPI RtlOemToUnicodeN(
+	LPWSTR unistr,
+	DWORD unilen,
+	LPDWORD reslen,
+	LPSTR oemstr,
+	DWORD oemlen)
+{
+	UINT len;
+	int i;
+
+	TRACE("%p %lu, %p, %s, %lu\n", oemstr, oemlen, reslen, debugstr_w(unistr), unilen);
+
+	len = (unilen/sizeof(WCHAR) < oemlen) ? unilen/sizeof(WCHAR) : oemlen;
+
+	for (i = len-1; i>=0; i--)
+	  unistr[i] = (WCHAR)oemstr[i];
+
+	if (reslen) *reslen = len * 2;
+	return 0;
+}
+
+
+/**************************************************************************
+ *	RtlUnicodeToOemN
+ */
+NTSTATUS
+WINAPI RtlUnicodeToOemN(
+	LPSTR oemstr,
+	DWORD oemlen,
+	LPDWORD reslen,
+	LPWSTR unistr,
+	DWORD unilen)
+{
+	UINT len;
+	int i;
+
+	TRACE("%p %lu, %p, %s, %lu\n", oemstr, oemlen, reslen, debugstr_w(unistr), unilen);
+
+	len = (oemlen < unilen/sizeof(WCHAR)) ? unilen/sizeof(WCHAR) : oemlen;
+
+	for (i = len-1; i>=0; i--)
+	  oemstr[i] = (CHAR)unistr[i];
+
+	if (reslen) *reslen = len * 2;
+	return 0;
+}
+
+/**************************************************************************
+ *	RtlUpcaseUnicodeToOemN
+ */
+NTSTATUS
+WINAPI RtlUpcaseUnicodeToOemN(
+	LPSTR oemstr,
+	DWORD oemlen,
+	LPDWORD reslen,
+	LPWSTR unistr,
+	DWORD unilen)
+{
+	UINT len;
+	int i;
+
+	TRACE("%p %lu, %p, %s, %lu\n", oemstr, oemlen, reslen, debugstr_w(unistr), unilen);
+
+	len = (oemlen < unilen/sizeof(WCHAR)) ? unilen/sizeof(WCHAR) : oemlen;
+
+	for (i = len-1; i>=0; i--)
+	  oemstr[i] = toupper((CHAR)unistr[i]);
+
+	if (reslen) *reslen = len * 2;
+	return 0;
+}
+
+/**************************************************************************
+ *	RtlUnicodeToMultiByteN
+ */
+NTSTATUS WINAPI RtlUnicodeToMultiByteN(
+	PCHAR  MbString,
+	ULONG  MbSize,
+	PULONG ResultSize,
+	PWCHAR UnicodeString,
+	ULONG  UnicodeSize)
+{
+        int Size = 0, i;
+
+	TRACE("(%p,%lu,%p,%p(%s),%lu)\n",
+	MbString, MbSize, ResultSize, UnicodeString, debugstr_w(UnicodeString), UnicodeSize);
+
+	Size = (UnicodeSize > (MbSize*sizeof(WCHAR))) ? MbSize: UnicodeSize/sizeof(WCHAR);
+
+	if (ResultSize != NULL) *ResultSize = Size;
+
+	for(i = 0; i < Size; i++)
+	{
+	  *(MbString++) = *(UnicodeString++);
+        }
+	return STATUS_SUCCESS;      
+}
+
+/*
+	STRING SIZE
+
+	Rtlx* supports multibyte
+*/
+
+/**************************************************************************
+ *	RtlxOemStringToUnicodeSize
  */
 UINT WINAPI RtlxOemStringToUnicodeSize(PSTRING str)
 {
@@ -262,7 +538,7 @@
 }
 
 /**************************************************************************
- *                 RtlxAnsiStringToUnicodeSize		[NTDLL.548]
+ *	RtlxAnsiStringToUnicodeSize
  */
 UINT WINAPI RtlxAnsiStringToUnicodeSize(PANSI_STRING str)
 {
@@ -270,13 +546,29 @@
 }
 
 /**************************************************************************
- *                 RtlIsTextUnicode			[NTDLL.417]
+ *	RtlxUnicodeStringToOemSize
+ *
+ */
+UINT WINAPI RtlxUnicodeStringToOemSize(PUNICODE_STRING str)
+{
+	return str->Length+1;
+}
+
+/*
+	MISC
+*/
+
+/**************************************************************************
+ *	RtlIsTextUnicode
  *
  *	Apply various feeble heuristics to guess whether
  *	the text buffer contains Unicode.
  *	FIXME: should implement more tests.
  */
-DWORD WINAPI RtlIsTextUnicode(LPVOID buf, DWORD len, DWORD *pf)
+DWORD WINAPI RtlIsTextUnicode(
+	LPVOID buf,
+	DWORD len,
+	DWORD *pf)
 {
 	LPWSTR s = buf;
 	DWORD flags = -1, out_flags = 0;
@@ -312,15 +604,15 @@
 	return len;
 }
 
-
-/******************************************************************************
- *	RtlCompareUnicodeString	[NTDLL] 
+/**************************************************************************
+ *	RtlPrefixUnicodeString
  */
-NTSTATUS WINAPI RtlCompareUnicodeString(
-	PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive) 
+NTSTATUS WINAPI RtlPrefixUnicodeString(
+	PUNICODE_STRING a,
+	PUNICODE_STRING b,
+	DWORD x)
 {
-	FIXME("(%s,%s,0x%08x),stub!\n",debugstr_w(String1->Buffer),debugstr_w(String1->Buffer),CaseInSensitive);
-	return 0;
+	TRACE("(%s,%s,%lx)\n",debugstr_us(a),debugstr_us(b),x);
+	return STATUS_SUCCESS;
 }
 
-
diff --git a/dlls/ntdll/sec.c b/dlls/ntdll/sec.c
index 251db26..cabe235 100644
--- a/dlls/ntdll/sec.c
+++ b/dlls/ntdll/sec.c
@@ -26,6 +26,8 @@
 
 DEFAULT_DEBUG_CHANNEL(ntdll)
 
+#define NT_SUCCESS(status) (status == STATUS_SUCCESS)
+
 /*
  *	SID FUNCTIONS
  */
@@ -34,95 +36,212 @@
  *  RtlAllocateAndInitializeSid		[NTDLL.265] 
  *
  */
-BOOLEAN WINAPI RtlAllocateAndInitializeSid (PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
-	DWORD nSubAuthorityCount,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8,DWORD x9,DWORD x10, PSID pSid) 
+BOOLEAN WINAPI RtlAllocateAndInitializeSid (
+	PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
+	BYTE nSubAuthorityCount,
+	DWORD nSubAuthority0, DWORD nSubAuthority1,
+	DWORD nSubAuthority2, DWORD nSubAuthority3,
+	DWORD nSubAuthority4, DWORD nSubAuthority5,
+	DWORD nSubAuthority6, DWORD nSubAuthority7,
+	PSID *pSid )
 {
-	FIXME("(%p,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p),stub!\n",
-		pIdentifierAuthority,nSubAuthorityCount,x3,x4,x5,x6,x7,x8,x9,x10,pSid);
-	return 0;
+	TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
+		pIdentifierAuthority,nSubAuthorityCount,
+		nSubAuthority0, nSubAuthority1,	nSubAuthority2, nSubAuthority3,
+		nSubAuthority4, nSubAuthority5,	nSubAuthority6, nSubAuthority7, pSid);
+
+	if (!(*pSid = HeapAlloc( GetProcessHeap(), 0, RtlLengthRequiredSid(nSubAuthorityCount))))
+	  return FALSE;
+
+	(*pSid)->Revision = SID_REVISION;
+
+	if (pIdentifierAuthority)
+	  memcpy(&(*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
+	*GetSidSubAuthorityCount(*pSid) = nSubAuthorityCount;
+
+	if (nSubAuthorityCount > 0)
+          *GetSidSubAuthority(*pSid, 0) = nSubAuthority0;
+	if (nSubAuthorityCount > 1)
+          *GetSidSubAuthority(*pSid, 1) = nSubAuthority1;
+	if (nSubAuthorityCount > 2)
+          *GetSidSubAuthority(*pSid, 2) = nSubAuthority2;
+	if (nSubAuthorityCount > 3)
+          *GetSidSubAuthority(*pSid, 3) = nSubAuthority3;
+	if (nSubAuthorityCount > 4)
+          *GetSidSubAuthority(*pSid, 4) = nSubAuthority4;
+	if (nSubAuthorityCount > 5)
+          *GetSidSubAuthority(*pSid, 5) = nSubAuthority5;
+        if (nSubAuthorityCount > 6)
+	  *GetSidSubAuthority(*pSid, 6) = nSubAuthority6;
+	if (nSubAuthorityCount > 7)
+          *GetSidSubAuthority(*pSid, 7) = nSubAuthority7;
+
+	return STATUS_SUCCESS;
 }
 /******************************************************************************
  *  RtlEqualSid		[NTDLL.352] 
  *
  */
-DWORD WINAPI RtlEqualSid(DWORD x1,DWORD x2) 
-{	
-	FIXME("(0x%08lx,0x%08lx),stub!\n", x1,x2);
-	return TRUE;
+BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
+{
+    if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
+        return FALSE;
+
+    if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
+        return FALSE;
+
+    if (memcmp(pSid1, pSid2, GetLengthSid(pSid1)) != 0)
+        return FALSE;
+
+    return TRUE;
 }
 
 /******************************************************************************
+ * RtlEqualPrefixSid	[ntdll.]
+ */
+BOOL WINAPI RtlEqualPrefixSid (PSID pSid1, PSID pSid2) 
+{
+    if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
+        return FALSE;
+
+    if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
+        return FALSE;
+
+    if (memcmp(pSid1, pSid2, RtlLengthRequiredSid(pSid1->SubAuthorityCount - 1)) != 0)
+        return FALSE;
+
+    return TRUE;
+}
+
+
+/******************************************************************************
  *  RtlFreeSid		[NTDLL.376] 
  */
-DWORD WINAPI RtlFreeSid(DWORD x1) 
+DWORD WINAPI RtlFreeSid(PSID pSid) 
 {
-	FIXME("(0x%08lx),stub!\n", x1);
-	return TRUE;
+	TRACE("(%p)\n", pSid);
+	HeapFree( GetProcessHeap(), 0, pSid );
+	return STATUS_SUCCESS;
 }
 
 /**************************************************************************
- *                 RtlLengthRequiredSid			[NTDLL.427]
+ * RtlLengthRequiredSid	[NTDLL.427]
+ *
+ * PARAMS
+ *   nSubAuthorityCount []
  */
 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
 {
-	return sizeof(DWORD)*nrofsubauths+sizeof(SID);
+	return (nrofsubauths-1)*sizeof(DWORD) + sizeof(SID);
 }
 
 /**************************************************************************
  *                 RtlLengthSid				[NTDLL.429]
  */
-DWORD WINAPI RtlLengthSid(PSID sid)
+DWORD WINAPI RtlLengthSid(PSID pSid)
 {
-	TRACE("sid=%p\n",sid);
-	if (!sid)
-	  return FALSE; 
-	return sizeof(DWORD)*sid->SubAuthorityCount+sizeof(SID);
+	TRACE("sid=%p\n",pSid);
+	if (!pSid) return 0; 
+	return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid));
 }
 
 /**************************************************************************
  *                 RtlInitializeSid			[NTDLL.410]
  */
-DWORD WINAPI RtlInitializeSid(PSID PSID,PSID_IDENTIFIER_AUTHORITY PSIDauth,
-                              DWORD c)
+BOOL WINAPI RtlInitializeSid(
+	PSID pSid,
+	PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
+	BYTE nSubAuthorityCount)
 {
-	BYTE	a = c&0xff;
+	int i;
+	if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
+	  return FALSE;
 
-	if (a>=SID_MAX_SUB_AUTHORITIES)
-		return a;
-	PSID->SubAuthorityCount = a;
-	PSID->Revision		 = SID_REVISION;
-	memcpy(&(PSID->IdentifierAuthority),PSIDauth,sizeof(SID_IDENTIFIER_AUTHORITY));
-	return STATUS_SUCCESS;
+	pSid->Revision = SID_REVISION;
+	pSid->SubAuthorityCount = nSubAuthorityCount;
+	if (pIdentifierAuthority)
+	  memcpy(&pSid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
+
+	for (i = 0; i < nSubAuthorityCount; i++)
+	  *GetSidSubAuthority(pSid, i) = 0;
+
+	return TRUE;
 }
 
 /**************************************************************************
  *                 RtlSubAuthoritySid			[NTDLL.497]
+ *
+ * PARAMS
+ *   pSid          []
+ *   nSubAuthority []
  */
-LPDWORD WINAPI RtlSubAuthoritySid(PSID PSID,DWORD nr)
+LPDWORD WINAPI RtlSubAuthoritySid( PSID pSid, DWORD nSubAuthority )
 {
-	return &(PSID->SubAuthority[nr]);
+	return &(pSid->SubAuthority[nSubAuthority]);
+}
+
+/**************************************************************************
+ * RtlIdentifierAuthoritySid	[NTDLL.395]
+ *
+ * PARAMS
+ *   pSid []
+ */
+PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid( PSID pSid )
+{
+	return &(pSid->IdentifierAuthority);
 }
 
 /**************************************************************************
  *                 RtlSubAuthorityCountSid		[NTDLL.496]
+ *
+ * PARAMS
+ *   pSid          []
+ *   nSubAuthority []
  */
-
-LPBYTE WINAPI RtlSubAuthorityCountSid(PSID PSID)
+LPBYTE WINAPI RtlSubAuthorityCountSid(PSID pSid)
 {
-	return ((LPBYTE)PSID)+1;
+	return &(pSid->SubAuthorityCount);
 }
 
 /**************************************************************************
  *                 RtlCopySid				[NTDLL.302]
  */
-DWORD WINAPI RtlCopySid(DWORD len,PSID to,PSID from)
-{	if (!from)
-		return 0;
-	if (len<(from->SubAuthorityCount*4+8))
-		return STATUS_BUFFER_TOO_SMALL;
-	memmove(to,from,from->SubAuthorityCount*4+8);
-	return STATUS_SUCCESS;
+DWORD WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
+{
+	if (!pSourceSid || !RtlValidSid(pSourceSid) ||
+	    (nDestinationSidLength < RtlLengthSid(pSourceSid)))
+          return FALSE;
+
+	if (nDestinationSidLength < (pSourceSid->SubAuthorityCount*4+8))
+	  return FALSE;
+
+	memmove(pDestinationSid, pSourceSid, pSourceSid->SubAuthorityCount*4+8);
+	return TRUE;
 }
+/******************************************************************************
+ * RtlValidSid [NTDLL.532]
+ *
+ * PARAMS
+ *   pSid []
+ */
+BOOL WINAPI
+RtlValidSid( PSID pSid )
+{
+    if (IsBadReadPtr(pSid, 4))
+    {
+        WARN("(%p): invalid pointer!\n", pSid);
+        return FALSE;
+    }
+
+    if (pSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
+        return FALSE;
+
+    if (!pSid || pSid->Revision != SID_REVISION)
+        return FALSE;
+
+    return TRUE;
+}
+
 
 /*
  *	security descriptor functions
@@ -387,6 +506,19 @@
 	return STATUS_SUCCESS;
 } 
 
+/**************************************************************************
+ *                 RtlMakeSelfRelativeSD		[NTDLL]
+ */
+NTSTATUS WINAPI RtlMakeSelfRelativeSD(
+	IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
+	IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
+	IN OUT LPDWORD lpdwBufferLength)
+{
+	FIXME("(%p,%p,%p(%lu))\n", pAbsoluteSecurityDescriptor,
+	pSelfRelativeSecurityDescriptor, lpdwBufferLength,*lpdwBufferLength);
+	return STATUS_SUCCESS;
+}
+
 /*
  *	access control list's
  */
@@ -397,8 +529,10 @@
  * NOTES
  *    This should return NTSTATUS
  */
-DWORD WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
+NTSTATUS WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
 {
+	TRACE("%p 0x%08lx 0x%08lx\n", acl, size, rev);
+
 	if (rev!=ACL_REVISION)
 		return STATUS_INVALID_PARAMETER;
 	if (size<sizeof(ACL))
@@ -470,9 +604,14 @@
 /******************************************************************************
  *  RtlAddAccessAllowedAce		[NTDLL] 
  */
-DWORD WINAPI RtlAddAccessAllowedAce(DWORD x1,DWORD x2,DWORD x3,DWORD x4) 
+BOOL WINAPI RtlAddAccessAllowedAce(
+	IN OUT PACL pAcl,
+	IN DWORD dwAceRevision,
+	IN DWORD AccessMask,
+	IN PSID pSid)
 {
-	FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
+	FIXME("(%p,0x%08lx,0x%08lx,%p),stub!\n",
+	pAcl, dwAceRevision, AccessMask, pSid);
 	return 0;
 }
 
@@ -498,3 +637,53 @@
 	return 0;
 }
 
+/******************************************************************************
+ *  RtlImpersonateSelf		[NTDLL] 
+ */
+BOOL WINAPI
+RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
+{
+	FIXME("(%08x), stub\n", ImpersonationLevel);
+	return TRUE;
+}
+
+NTSTATUS WINAPI 
+NtAccessCheck(
+	IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+	IN HANDLE ClientToken,
+	IN ACCESS_MASK DesiredAccess,
+	IN PGENERIC_MAPPING GenericMapping,
+	OUT PPRIVILEGE_SET PrivilegeSet,
+	OUT PULONG ReturnLength,
+	OUT PULONG GrantedAccess,
+	OUT PBOOLEAN AccessStatus)
+{
+	FIXME("(%p, %04x, %08lx, %p, %p, %p, %p, %p), stub\n",
+          SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping, 
+          PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
+	*AccessStatus = TRUE;
+	return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI
+NtSetSecurityObject(
+        IN HANDLE Handle,
+        IN SECURITY_INFORMATION SecurityInformation,
+        IN PSECURITY_DESCRIPTOR SecurityDescriptor) 
+{
+	FIXME("0x%08x 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
+	return STATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * RtlGetControlSecurityDescriptor
+ */
+
+NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
+	PSECURITY_DESCRIPTOR  pSecurityDescriptor,
+	PSECURITY_DESCRIPTOR_CONTROL pControl,
+	LPDWORD lpdwRevision)
+{
+	FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor,pControl,lpdwRevision);
+	return STATUS_SUCCESS;
+}		
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index 9d2a352..4fb7f8b 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -9,16 +9,46 @@
 #include "debugstr.h"
 #include "debugtools.h"
 
+#include "winerror.h"
+#include "server.h"
 #include "ntddk.h"
+#include "ntdll_misc.h"
 
 DEFAULT_DEBUG_CHANNEL(ntdll)
 
+#define nt_server_call(kind) (ret=ErrorCodeToStatus(server_call_noerr(kind)))
+
+/* helper to make the server functions return STATUS_ codes */
+static NTSTATUS ErrorCodeToStatus (DWORD Error)
+{
+        TRACE("err=%lu\n", Error);
+        switch (Error)
+        {
+          case NO_ERROR:                        return STATUS_SUCCESS;
+          default:
+            FIXME("Error code %lu not implemented\n", Error);
+        }
+        return STATUS_UNSUCCESSFUL;
+}
+
+/* copy a key name into the request buffer */
+static inline NTSTATUS copy_nameU( LPWSTR Dest, PUNICODE_STRING Name )
+{
+        if (Name->Buffer)
+        {
+          if ((Name->Length) > MAX_PATH) return STATUS_BUFFER_OVERFLOW;
+          lstrcpyW( Dest, Name->Buffer );
+        }
+        else Dest[0] = 0;
+        return STATUS_SUCCESS;
+}
+
 /*
- *	Semaphore
+ *	Semaphores
  */
 
 /******************************************************************************
- *  NtCreateSemaphore	[NTDLL] 
+ *  NtCreateSemaphore
  */
 NTSTATUS WINAPI NtCreateSemaphore(
 	OUT PHANDLE SemaphoreHandle,
@@ -27,29 +57,52 @@
 	IN ULONG InitialCount,
 	IN ULONG MaximumCount) 
 {
-	FIXME("(%p,0x%08lx,%p(%s),0x%08lx,0x%08lx) stub!\n",
-	SemaphoreHandle, DesiredAccess, ObjectAttributes, 
-	ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL,
-	InitialCount, MaximumCount);
-	return 0;
+	struct create_semaphore_request *req = get_req_buffer();
+	HRESULT ret;
+
+	FIXME("(%p,0x%08lx,%p,0x%08lx,0x%08lx) stub!\n",
+	SemaphoreHandle, DesiredAccess, ObjectAttributes, InitialCount, MaximumCount);
+	dump_ObjectAttributes(ObjectAttributes);
+
+	if ((MaximumCount <= 0) || (InitialCount < 0) || (InitialCount > MaximumCount))
+	  return STATUS_INVALID_PARAMETER;
+
+	*SemaphoreHandle = 0;
+	req->initial = InitialCount;
+	req->max     = MaximumCount;
+	req->inherit = ObjectAttributes->Attributes & OBJ_INHERIT;
+	copy_nameU( req->name, ObjectAttributes->ObjectName );
+	if (nt_server_call( REQ_CREATE_SEMAPHORE ) != STATUS_SUCCESS) return ret;
+	*SemaphoreHandle = req->handle;
+	return ret;
 }
 
 /******************************************************************************
- *  NtOpenSemaphore	[NTDLL] 
+ *  NtOpenSemaphore
+ *
+ * FIXME
  */
 NTSTATUS WINAPI NtOpenSemaphore(
 	IN HANDLE SemaphoreHandle,
 	IN ACCESS_MASK DesiredAcces,
 	IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-	FIXME("(0x%08x,0x%08lx,%p(%s)) stub!\n",
-	SemaphoreHandle, DesiredAcces, ObjectAttributes,
-	ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL);
-	return 0;
+	struct open_semaphore_request *req = get_req_buffer();
+	HRESULT ret;
+
+	FIXME("(0x%08x,0x%08lx,%p) stub!\n",
+	SemaphoreHandle, DesiredAcces, ObjectAttributes);
+	dump_ObjectAttributes(ObjectAttributes);
+
+	req->access  = DesiredAcces;
+	req->inherit = ObjectAttributes->Attributes & OBJ_INHERIT;
+	copy_nameU( req->name, ObjectAttributes->ObjectName );
+	if (nt_server_call( REQ_OPEN_SEMAPHORE ) != STATUS_SUCCESS) return -1;
+	return req->handle;
 }
 
 /******************************************************************************
- *  NtQuerySemaphore	[NTDLL] 
+ *  NtQuerySemaphore
  */
 NTSTATUS WINAPI NtQuerySemaphore(
 	HANDLE SemaphoreHandle,
@@ -60,27 +113,39 @@
 {
 	FIXME("(0x%08x,%p,%p,0x%08lx,%p) stub!\n",
 	SemaphoreHandle, SemaphoreInformationClass, SemaphoreInformation, Length, ReturnLength);
-	return 0;
+	return STATUS_SUCCESS;
 }
 /******************************************************************************
- *  NtReleaseSemaphore	[NTDLL] 
+ *  NtReleaseSemaphore
  */
 NTSTATUS WINAPI NtReleaseSemaphore(
 	IN HANDLE SemaphoreHandle,
 	IN ULONG ReleaseCount,
 	IN PULONG PreviousCount)
 {
+	struct release_semaphore_request *req = get_req_buffer();
+	HRESULT ret;
+
 	FIXME("(0x%08x,0x%08lx,%p,) stub!\n",
 	SemaphoreHandle, ReleaseCount, PreviousCount);
-	return 0;
+
+	if (ReleaseCount < 0) return STATUS_INVALID_PARAMETER;
+
+	req->handle = SemaphoreHandle;
+	req->count  = ReleaseCount;
+	if (nt_server_call( REQ_RELEASE_SEMAPHORE ) == STATUS_SUCCESS)
+	{
+	  if (PreviousCount) *PreviousCount = req->prev_count;
+	}
+	return ret;
 }
 
 /*
- *	Event
+ *	Events
  */
  
 /**************************************************************************
- *		NtCreateEvent				[NTDLL.71]
+ * NtCreateEvent
  */
 NTSTATUS WINAPI NtCreateEvent(
 	OUT PHANDLE EventHandle,
@@ -89,36 +154,128 @@
 	IN BOOLEAN ManualReset,
 	IN BOOLEAN InitialState)
 {
-	FIXME("(%p,0x%08lx,%p(%s),%08x,%08x): empty stub\n",
-	EventHandle,DesiredAccess,ObjectAttributes,
-	ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL,
-	ManualReset,InitialState);
-	return 0;
+	struct create_event_request *req = get_req_buffer();
+	HRESULT ret;
+
+	FIXME("(%p,0x%08lx,%p,%08x,%08x): empty stub\n",
+	EventHandle,DesiredAccess,ObjectAttributes,ManualReset,InitialState);
+	dump_ObjectAttributes(ObjectAttributes);
+
+	*EventHandle = 0;
+	req->manual_reset = ManualReset;
+	req->initial_state = InitialState;
+	req->inherit = ObjectAttributes->Attributes & OBJ_INHERIT;
+	copy_nameU( req->name, ObjectAttributes->ObjectName );
+	if (nt_server_call( REQ_CREATE_EVENT ) != STATUS_SUCCESS) return ret;
+	*EventHandle = req->handle;
+	return STATUS_SUCCESS;
 }
 
 /******************************************************************************
- *  NtOpenEvent		[NTDLL] 
+ *  NtOpenEvent
  */
 NTSTATUS WINAPI NtOpenEvent(
 	OUT PHANDLE EventHandle,
 	IN ACCESS_MASK DesiredAccess,
 	IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-	FIXME("(%p,0x%08lx,%p(%s)),stub!\n",
-	EventHandle,DesiredAccess,ObjectAttributes,
-	ObjectAttributes ? debugstr_w(ObjectAttributes->ObjectName->Buffer) : NULL);
-	return 0;
+	struct open_event_request *req = get_req_buffer();
+	HRESULT ret;
+
+	FIXME("(%p,0x%08lx,%p),stub!\n",
+	EventHandle,DesiredAccess,ObjectAttributes);
+	dump_ObjectAttributes(ObjectAttributes);
+
+	*EventHandle = 0;
+	req->access  = DesiredAccess;
+	req->inherit = ObjectAttributes->Attributes & OBJ_INHERIT;
+	copy_nameU( req->name, ObjectAttributes->ObjectName );
+	if (nt_server_call( REQ_OPEN_EVENT ) != STATUS_SUCCESS) return ret;
+	*EventHandle = req->handle;
+	return ret;
+}
+
+/***********************************************************************
+ * EVENT_Operation
+ *
+ * Execute an event operation (set,reset,pulse).
+ */
+static NTSTATUS EVENT_Operation(
+	HANDLE handle,
+	PULONG NumberOfThreadsReleased,
+	enum event_op op )
+{
+	struct event_op_request *req = get_req_buffer();
+	HRESULT ret;
+
+	req->handle = handle;
+	req->op     = op;
+	nt_server_call( REQ_EVENT_OP );
+	return ret;
 }
 
 /******************************************************************************
- *  NtSetEvent		[NTDLL] 
+ *  NtSetEvent
  */
 NTSTATUS WINAPI NtSetEvent(
 	IN HANDLE EventHandle,
 	PULONG NumberOfThreadsReleased)
 {
-	FIXME("(0x%08x,%p)\n",
-	EventHandle, NumberOfThreadsReleased);
-	return 0;
+	FIXME("(0x%08x,%p)\n", EventHandle, NumberOfThreadsReleased);
+
+	return EVENT_Operation(EventHandle, NumberOfThreadsReleased, SET_EVENT);
 }
 
+/******************************************************************************
+ *  NtResetEvent
+ */
+NTSTATUS WINAPI NtResetEvent(
+	IN HANDLE EventHandle,
+	PULONG NumberOfThreadsReleased)
+{
+	FIXME("(0x%08x,%p)\n", EventHandle, NumberOfThreadsReleased);
+
+	return EVENT_Operation(EventHandle, NumberOfThreadsReleased, RESET_EVENT);
+}
+
+/******************************************************************************
+ *  NtClearEvent
+ *
+ * FIXME
+ *   same as NtResetEvent ???
+ */
+NTSTATUS WINAPI NtClearEvent (
+	IN HANDLE EventHandle)
+{
+	FIXME("(0x%08x)\n", EventHandle);
+	return EVENT_Operation(EventHandle, NULL, RESET_EVENT);
+}
+
+/******************************************************************************
+ *  NtPulseEvent
+ *
+ * FIXME
+ *   PulseCount
+ */
+NTSTATUS WINAPI NtPulseEvent(
+	IN HANDLE EventHandle,
+	IN PULONG PulseCount)
+{
+	FIXME("(0x%08x,%p)\n", EventHandle, PulseCount);
+
+	return EVENT_Operation(EventHandle, NULL, PULSE_EVENT);
+}
+
+/******************************************************************************
+ *  NtQueryEvent
+ */
+NTSTATUS WINAPI NtQueryEvent (
+	IN  HANDLE EventHandle,
+	IN  UINT EventInformationClass,
+	OUT PVOID EventInformation,
+	IN  ULONG EventInformationLength,
+	OUT PULONG  ReturnLength)
+{
+	FIXME("(0x%08x)\n", EventHandle);
+	return STATUS_SUCCESS;
+}
diff --git a/include/ntddk.h b/include/ntddk.h
index 1abb28b..787d2ce 100644
--- a/include/ntddk.h
+++ b/include/ntddk.h
@@ -10,6 +10,8 @@
 #include "winnt.h"
 #include "winbase.h"	/* fixme: should be taken out sometimes */
 
+#include "pshpack1.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -30,13 +32,89 @@
 
 typedef VOID (NTAPI *PIO_APC_ROUTINE) ( PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved );
 
-typedef enum _KEY_INFORMATION_CLASS {
+/*
+	registry 
+ */
+
+ /* key information */
+typedef struct _KEY_BASIC_INFORMATION {
+	FILETIME	LastWriteTime;
+	ULONG		TitleIndex;
+	ULONG		NameLength;
+	WCHAR		Name[1];
+} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;
+
+typedef struct _KEY_NODE_INFORMATION 
+{
+	FILETIME	LastWriteTime;
+	ULONG		TitleIndex;
+	ULONG		ClassOffset;
+	ULONG		ClassLength;
+	ULONG		NameLength;
+	WCHAR		Name[1];
+/*	Class[1]; */
+} KEY_NODE_INFORMATION, *PKEY_NODE_INFORMATION;
+
+typedef struct _KEY_FULL_INFORMATION 
+{
+	FILETIME	LastWriteTime;
+	ULONG		TitleIndex;
+	ULONG		ClassOffset;
+	ULONG		ClassLength;
+	ULONG		SubKeys;
+	ULONG		MaxNameLen;
+	ULONG		MaxClassLen;
+	ULONG		Values;
+	ULONG		MaxValueNameLen;
+	ULONG		MaxValueDataLen;
+	WCHAR		Class[1];
+} KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION;
+
+typedef enum _KEY_INFORMATION_CLASS 
+{
 	KeyBasicInformation,
 	KeyNodeInformation,
 	KeyFullInformation
 } KEY_INFORMATION_CLASS;
 
-typedef enum _KEY_VALUE_INFORMATION_CLASS {
+typedef struct _KEY_VALUE_ENTRY 
+{
+	PUNICODE_STRING	ValueName;
+	ULONG		DataLength;
+	ULONG		DataOffset;
+	ULONG		Type;
+} KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY;
+
+/* value information */
+typedef struct _KEY_VALUE_BASIC_INFORMATION 
+{
+	ULONG   TitleIndex;
+	ULONG   Type;
+	ULONG   NameLength;
+	WCHAR   Name[1];
+} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;
+
+typedef struct _KEY_VALUE_FULL_INFORMATION 
+{
+	ULONG   TitleIndex;
+	ULONG   Type;
+	ULONG   DataOffset;
+	ULONG   DataLength;
+	ULONG   NameLength;
+	WCHAR   Name[1];
+/*	UCHAR 	Data[1];*/
+} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
+
+typedef struct _KEY_VALUE_PARTIAL_INFORMATION 
+{
+	ULONG   TitleIndex;
+	ULONG   Type;
+	ULONG   DataLength;
+	UCHAR   Data[1];
+} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
+
+typedef enum _KEY_VALUE_INFORMATION_CLASS 
+{
 	KeyValueBasicInformation,
 	KeyValueFullInformation,
 	KeyValuePartialInformation,
@@ -44,6 +122,11 @@
 	KeyValuePartialInformationAlign64
 } KEY_VALUE_INFORMATION_CLASS;
 
+NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(
+	PUNICODE_STRING KeyPath);
+
+/*	thread information */
+
 typedef enum _THREADINFOCLASS 
 {	ThreadBasicInformation,
 	ThreadTimes,
@@ -65,6 +148,8 @@
 	MaxThreadInfoClass
 } THREADINFOCLASS;
 
+/*	file information */
+
 typedef enum _FILE_INFORMATION_CLASS {
 	FileDirectoryInformation = 1,
 	FileFullDirectoryInformation,
@@ -124,9 +209,8 @@
 
 } SECTION_INHERIT;
  
-/*
-	placeholder
-*/
+/*	object information */
+
 typedef enum _OBJECT_INFORMATION_CLASS
 {
 	DunnoTheConstants1
@@ -134,9 +218,7 @@
 } OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
 
 
-/*
- *	NtQuerySystemInformation
- */
+/*	system information */
 
 typedef enum SYSTEM_INFORMATION_CLASS
 {	Unknown1 = 1,
@@ -170,6 +252,8 @@
 	ULONG PeakPagefileUsage;
 } VM_COUNTERS, *PVM_COUNTERS;
 
+/* process information */
+
 typedef struct _PROCESS_INFO
 {	DWORD		Offset;		/* 00 offset to next PROCESS_INFO ok*/
 	DWORD		ThreadCount;	/* 04 number of ThreadInfo member ok */
@@ -317,9 +401,7 @@
 
 } TIMER_TYPE;
 
-/*
- *	token functions
- */
+/*	token functions */
  
 NTSTATUS WINAPI NtOpenProcessToken(
 	HANDLE ProcessHandle,
@@ -347,35 +429,58 @@
 	DWORD tokeninfolength,
 	LPDWORD retlen );
 
-/*
- *	sid functions
- */
+/*	sid functions */
 
 BOOLEAN WINAPI RtlAllocateAndInitializeSid (
 	PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
-	DWORD nSubAuthorityCount,
-	DWORD x3,
-	DWORD x4,
-	DWORD x5,
-	DWORD x6,
-	DWORD x7,
-	DWORD x8,
-	DWORD x9,
-	DWORD x10,
-	PSID pSid);
+	BYTE nSubAuthorityCount,
+	DWORD nSubAuthority0, DWORD nSubAuthority1,
+	DWORD nSubAuthority2, DWORD nSubAuthority3,
+	DWORD nSubAuthority4, DWORD nSubAuthority5,
+	DWORD nSubAuthority6, DWORD nSubAuthority7,
+	PSID *pSid );
 	
-DWORD WINAPI RtlEqualSid(DWORD x1,DWORD x2);
-DWORD WINAPI RtlFreeSid(DWORD x1);
-DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths);
-DWORD WINAPI RtlLengthSid(PSID sid);
-DWORD WINAPI RtlInitializeSid(PSID PSID,PSID_IDENTIFIER_AUTHORITY PSIDauth, DWORD c);
-LPDWORD WINAPI RtlSubAuthoritySid(PSID PSID,DWORD nr);
-LPBYTE WINAPI RtlSubAuthorityCountSid(PSID PSID);
-DWORD WINAPI RtlCopySid(DWORD len,PSID to,PSID from);
+BOOL WINAPI RtlInitializeSid(
+	PSID pSid,
+	PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
+	BYTE nSubAuthorityCount);
+	
+DWORD WINAPI RtlFreeSid(
+	PSID pSid);
 
-/*
- *	security descriptor functions
- */
+BOOL WINAPI RtlEqualSid(
+	PSID pSid1,
+	PSID pSid2 );
+	
+DWORD WINAPI RtlLengthRequiredSid(
+	DWORD nrofsubauths);
+
+DWORD WINAPI RtlLengthSid(
+	PSID sid);
+
+LPDWORD WINAPI RtlSubAuthoritySid(
+	PSID PSID,
+	DWORD nr);
+
+LPBYTE WINAPI RtlSubAuthorityCountSid(
+	PSID pSid);
+
+DWORD WINAPI RtlCopySid(
+	DWORD len,
+	PSID to,
+	PSID from);
+	
+BOOL WINAPI RtlValidSid(
+	PSID pSid);
+
+BOOL WINAPI RtlEqualPrefixSid(
+	PSID pSid1,
+	PSID pSid2);
+
+PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid(
+	PSID pSid );
+
+/*	security descriptor functions */
 
 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
 	PSECURITY_DESCRIPTOR lpsd,
@@ -431,12 +536,22 @@
 	PSID *Group,
 	PBOOLEAN GroupDefaulted);
 
-/*	##############################
-	######	ACL FUNCTIONS	######
-	##############################
-*/
+NTSTATUS WINAPI RtlMakeSelfRelativeSD(
+	IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
+	IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
+	IN OUT LPDWORD lpdwBufferLength);
 
-DWORD WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev);
+NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
+	PSECURITY_DESCRIPTOR  pSecurityDescriptor,
+	PSECURITY_DESCRIPTOR_CONTROL pControl,
+	LPDWORD lpdwRevision);
+
+/*	acl functions */
+
+NTSTATUS WINAPI RtlCreateAcl(
+	PACL acl,
+	DWORD size,
+	DWORD rev);
 
 BOOLEAN WINAPI RtlFirstFreeAce(
 	PACL acl,
@@ -449,35 +564,112 @@
 	PACE_HEADER acestart,
 	DWORD acelen);
 	
-DWORD WINAPI RtlAddAccessAllowedAce(DWORD x1,DWORD x2,DWORD x3,DWORD x4);
-DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce );
+BOOL WINAPI RtlAddAccessAllowedAce(
+	IN OUT PACL pAcl,
+	IN DWORD dwAceRevision,
+	IN DWORD AccessMask,
+	IN PSID pSid);
 
-/*
- *	string functions
- */
+BOOL WINAPI AddAccessAllowedAceEx(
+	IN OUT PACL pAcl,
+	IN DWORD dwAceRevision,
+	IN DWORD AceFlags,
+	IN DWORD AccessMask,
+	IN PSID pSid);
 
-DWORD WINAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING uni,PANSI_STRING ansi,BOOLEAN doalloc);
-DWORD WINAPI RtlOemStringToUnicodeString(PUNICODE_STRING uni,PSTRING ansi,BOOLEAN doalloc);
-DWORD WINAPI RtlMultiByteToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen);
-DWORD WINAPI RtlOemToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen);
-VOID WINAPI RtlInitAnsiString(PANSI_STRING target,LPCSTR source);
-VOID WINAPI RtlInitString(PSTRING target,LPCSTR source);
-VOID WINAPI RtlInitUnicodeString(PUNICODE_STRING target,LPCWSTR source);
-VOID WINAPI RtlFreeUnicodeString(PUNICODE_STRING str);
-VOID WINAPI RtlFreeAnsiString(PANSI_STRING AnsiString);
-DWORD WINAPI RtlUnicodeToOemN(LPSTR oemstr,DWORD oemlen,LPDWORD reslen,LPWSTR unistr,DWORD unilen);
-DWORD WINAPI RtlUnicodeStringToOemString(PANSI_STRING oem,PUNICODE_STRING uni,BOOLEAN alloc);
-DWORD WINAPI RtlUnicodeStringToAnsiString(PANSI_STRING oem,PUNICODE_STRING uni,BOOLEAN alloc);
-DWORD WINAPI RtlEqualUnicodeString(PUNICODE_STRING s1,PUNICODE_STRING s2,DWORD x);
-DWORD WINAPI RtlUpcaseUnicodeString(PUNICODE_STRING dest,PUNICODE_STRING src,BOOLEAN doalloc);
-UINT WINAPI RtlxOemStringToUnicodeSize(PSTRING str);
-UINT WINAPI RtlxAnsiStringToUnicodeSize(PANSI_STRING str);
-DWORD WINAPI RtlIsTextUnicode(LPVOID buf, DWORD len, DWORD *pf);
-NTSTATUS WINAPI RtlCompareUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive);
+DWORD WINAPI RtlGetAce(
+	PACL pAcl,
+	DWORD dwAceIndex,
+	LPVOID *pAce );
 
-/*
- *	resource functions
- */
+/*	string functions */
+
+VOID WINAPI RtlInitAnsiString(
+	PANSI_STRING target,
+	LPCSTR source);
+	
+VOID WINAPI RtlInitString(
+	PSTRING target,
+	LPCSTR source);
+	
+VOID WINAPI RtlInitUnicodeString(
+	PUNICODE_STRING target,
+	LPCWSTR source);
+	
+VOID WINAPI RtlFreeUnicodeString(
+	PUNICODE_STRING str);
+	
+VOID WINAPI RtlFreeAnsiString(
+	PANSI_STRING AnsiString);
+
+NTSTATUS WINAPI RtlAnsiStringToUnicodeString(
+	PUNICODE_STRING uni,
+	PANSI_STRING ansi,
+	BOOLEAN doalloc);
+
+NTSTATUS WINAPI RtlOemStringToUnicodeString(
+	PUNICODE_STRING uni,
+	PSTRING ansi,
+	BOOLEAN doalloc);
+	
+NTSTATUS WINAPI RtlMultiByteToUnicodeN(
+	LPWSTR unistr,
+	DWORD unilen,
+	LPDWORD reslen,
+	LPSTR oemstr,
+	DWORD oemlen);
+	
+NTSTATUS WINAPI RtlOemToUnicodeN(
+	LPWSTR unistr,
+	DWORD unilen,
+	LPDWORD reslen,
+	LPSTR oemstr,
+	DWORD oemlen);
+	
+NTSTATUS WINAPI RtlUnicodeToOemN(
+	LPSTR oemstr,
+	DWORD oemlen,
+	LPDWORD reslen,
+	LPWSTR unistr,
+	DWORD unilen);
+
+NTSTATUS WINAPI RtlUnicodeStringToOemString(
+	PANSI_STRING oem,
+	PUNICODE_STRING uni,
+	BOOLEAN alloc);
+
+NTSTATUS WINAPI RtlUnicodeStringToAnsiString(
+	PANSI_STRING oem,
+	PUNICODE_STRING uni,
+	BOOLEAN alloc);
+
+BOOLEAN WINAPI RtlEqualUnicodeString(
+	PUNICODE_STRING s1,
+	PUNICODE_STRING s2,
+	BOOLEAN x);
+
+DWORD WINAPI RtlUpcaseUnicodeString(
+	PUNICODE_STRING dest,
+	PUNICODE_STRING src,
+	BOOLEAN doalloc);
+
+UINT WINAPI RtlxOemStringToUnicodeSize(
+	PSTRING str);
+
+UINT WINAPI RtlxAnsiStringToUnicodeSize(
+	PANSI_STRING str);
+
+DWORD WINAPI RtlIsTextUnicode(
+	LPVOID buf,
+	DWORD len,
+	DWORD *pf);
+
+NTSTATUS WINAPI RtlCompareUnicodeString(
+	PUNICODE_STRING String1,
+	PUNICODE_STRING String2,
+	BOOLEAN CaseInSensitive);
+
+/*	resource functions */
 
 typedef struct _RTL_RWLOCK {
 	CRITICAL_SECTION	rtlCS;
@@ -509,9 +701,7 @@
 VOID   WINAPI RtlDumpResource(
 	LPRTL_RWLOCK);
 
-/*
-	time functions
- */
+/*	time functions */
 
 typedef struct _TIME_FIELDS 
 {   CSHORT Year;
@@ -550,9 +740,7 @@
 	LPFILETIME ft,
 	LPDWORD timeret);
 
-/*
-	heap functions
-*/
+/*	heap functions */
 
 /* Data structure for heap definition. This includes various
    sizing parameters and callback routines, which, if left NULL,
@@ -582,55 +770,114 @@
 	ULONG Flags,
 	PVOID Address);
 
-/*
- *	misc
- */
-void WINAPIV DbgPrint(LPCSTR fmt, ...);
-void WINAPI NtRaiseException(PEXCEPTION_RECORD,PCONTEXT,BOOL);
-void WINAPI RtlRaiseException(PEXCEPTION_RECORD);
-void WINAPI RtlRaiseStatus(NTSTATUS);
-void WINAPI RtlUnwind(PEXCEPTION_FRAME,LPVOID,PEXCEPTION_RECORD,DWORD);
+/*	exception */
+
+void WINAPI NtRaiseException(
+	PEXCEPTION_RECORD,PCONTEXT,BOOL);
+
+void WINAPI RtlRaiseException(
+	PEXCEPTION_RECORD);
+
+void WINAPI RtlRaiseStatus(
+	NTSTATUS);
+
+void WINAPI RtlUnwind(
+	PEXCEPTION_FRAME,
+	LPVOID,
+	PEXCEPTION_RECORD,DWORD);
+
+/*	process environment block  */
 VOID WINAPI RtlAcquirePebLock(void);
 VOID WINAPI RtlReleasePebLock(void);
+
+/*	mathematics */
+INT WINAPI RtlExtendedLargeIntegerDivide(
+	LARGE_INTEGER dividend,
+	DWORD divisor,
+	LPDWORD rest);
+
+LARGE_INTEGER WINAPI RtlExtendedIntegerMultiply(
+	LARGE_INTEGER factor1,
+	INT factor2);
+
+/*	environment */
+DWORD WINAPI RtlCreateEnvironment(
+	DWORD x1,
+	DWORD x2);
+
+DWORD WINAPI RtlDestroyEnvironment(
+	DWORD x);
+
+DWORD WINAPI RtlQueryEnvironmentVariable_U(
+	DWORD x1,
+	PUNICODE_STRING key,
+	PUNICODE_STRING val) ;
+
+DWORD WINAPI RtlSetEnvironmentVariable(
+	DWORD x1,
+	PUNICODE_STRING key,
+	PUNICODE_STRING val);
+
+/*	object security */
+
+DWORD WINAPI RtlNewSecurityObject(
+	DWORD x1,
+	DWORD x2,
+	DWORD x3,
+	DWORD x4,
+	DWORD x5,
+	DWORD x6);
+
+DWORD WINAPI RtlDeleteSecurityObject(
+	DWORD x1);
+	
+NTSTATUS WINAPI 
+NtQuerySecurityObject(
+	IN HANDLE Object,
+	IN SECURITY_INFORMATION RequestedInformation,
+	OUT PSECURITY_DESCRIPTOR pSecurityDesriptor,
+	IN ULONG Length,
+	OUT PULONG ResultLength);
+
+NTSTATUS WINAPI
+NtSetSecurityObject(
+        IN HANDLE Handle,
+        IN SECURITY_INFORMATION SecurityInformation,
+        IN PSECURITY_DESCRIPTOR SecurityDescriptor);
+
+
+/*	misc */
+
+void WINAPIV DbgPrint(LPCSTR fmt, ...);
+
 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4);
 DWORD WINAPI RtlIntegerToChar(DWORD x1,DWORD x2,DWORD x3,DWORD x4);
-DWORD WINAPI RtlSetEnvironmentVariable(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val);
-DWORD WINAPI RtlNewSecurityObject(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6);
-DWORD WINAPI RtlDeleteSecurityObject(DWORD x1);
 LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x);
 DWORD WINAPI RtlNtStatusToDosError(DWORD error);
 BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type);
-INT WINAPI RtlExtendedLargeIntegerDivide(LARGE_INTEGER dividend, DWORD divisor, LPDWORD rest);
-LARGE_INTEGER WINAPI RtlExtendedIntegerMultiply(LARGE_INTEGER factor1,INT factor2);
-DWORD WINAPI RtlFormatCurrentUserKeyPath(PUNICODE_STRING String);
-DWORD WINAPI RtlOpenCurrentUser(DWORD x1, DWORD *x2);
-BOOLEAN WINAPI RtlDosPathNameToNtPathName_U( LPWSTR from,PUNICODE_STRING us,DWORD x2,DWORD x3);
-DWORD WINAPI RtlCreateEnvironment(DWORD x1,DWORD x2);
-DWORD WINAPI RtlDestroyEnvironment(DWORD x);
-DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) ;
 
-BOOL WINAPI IsValidSid(PSID);
-BOOL WINAPI EqualSid(PSID,PSID);
-BOOL WINAPI EqualPrefixSid(PSID,PSID);
-DWORD  WINAPI GetSidLengthRequired(BYTE);
-BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,
-                                       DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,
-                                       DWORD,PSID*);
-VOID*  WINAPI FreeSid(PSID);
-BOOL WINAPI InitializeSecurityDescriptor(SECURITY_DESCRIPTOR*,DWORD);
-BOOL WINAPI InitializeSid(PSID,PSID_IDENTIFIER_AUTHORITY,BYTE);
-DWORD* WINAPI GetSidSubAuthority(PSID,DWORD);
-BYTE * WINAPI GetSidSubAuthorityCount(PSID);
-DWORD  WINAPI GetLengthSid(PSID);
-BOOL WINAPI CopySid(DWORD,PSID,PSID);
-BOOL WINAPI LookupAccountSidA(LPCSTR,PSID,LPCSTR,LPDWORD,LPCSTR,LPDWORD,
-                                  PSID_NAME_USE);
-BOOL WINAPI LookupAccountSidW(LPCWSTR,PSID,LPCWSTR,LPDWORD,LPCWSTR,LPDWORD,
-                                  PSID_NAME_USE);
-PSID_IDENTIFIER_AUTHORITY WINAPI GetSidIdentifierAuthority(PSID);
+DWORD WINAPI RtlOpenCurrentUser(
+	IN ACCESS_MASK DesiredAccess,
+	OUT PHANDLE KeyHandle);
+
+BOOLEAN WINAPI RtlDosPathNameToNtPathName_U( LPWSTR from,PUNICODE_STRING us,DWORD x2,DWORD x3);
+BOOL WINAPI RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel);
+
+NTSTATUS WINAPI 
+NtAccessCheck(
+	IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+	IN HANDLE ClientToken,
+	IN ACCESS_MASK DesiredAccess,
+	IN PGENERIC_MAPPING GenericMapping,
+	OUT PPRIVILEGE_SET PrivilegeSet,
+	OUT PULONG ReturnLength,
+	OUT PULONG GrantedAccess,
+	OUT PBOOLEAN AccessStatus);
 
 #ifdef __cplusplus
 }
 #endif
 
+#include "poppack.h"
+
 #endif
diff --git a/include/ntdef.h b/include/ntdef.h
index dc07f68..edf0af8 100644
--- a/include/ntdef.h
+++ b/include/ntdef.h
@@ -4,6 +4,8 @@
 #include "basetsd.h"
 #include "windef.h"
 
+#include "pshpack1.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -80,8 +82,20 @@
 
 typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
 
+#define InitializeObjectAttributes(p,n,a,r,s) \
+{	(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
+	(p)->RootDirectory = r; \
+	(p)->Attributes = a; \
+	(p)->ObjectName = n; \
+	(p)->SecurityDescriptor = s; \
+	(p)->SecurityQualityOfService = NULL; \
+}
+
+
 #ifdef __cplusplus
 }
 #endif
 
+#include "poppack.h"
+
 #endif
diff --git a/include/ntsecapi.h b/include/ntsecapi.h
index 44fa0b5..473da89 100644
--- a/include/ntsecapi.h
+++ b/include/ntsecapi.h
@@ -32,6 +32,22 @@
 	PolicyDnsDomainInformation
 } POLICY_INFORMATION_CLASS, *PPOLICY_INFORMATION_CLASS;
 
+typedef ULONG POLICY_AUDIT_EVENT_OPTIONS, *PPOLICY_AUDIT_EVENT_OPTIONS;
+
+typedef struct
+{
+	BOOLEAN AuditingMode;
+	PPOLICY_AUDIT_EVENT_OPTIONS EventAuditingOptions;
+	ULONG MaximumAuditEventCount;
+} POLICY_AUDIT_EVENTS_INFO, *PPOLICY_AUDIT_EVENTS_INFO;
+
+typedef struct
+{
+    LSA_UNICODE_STRING Name;
+    PSID Sid;
+} POLICY_PRIMARY_DOMAIN_INFO, *PPOLICY_PRIMARY_DOMAIN_INFO;
+
+
 NTSTATUS WINAPI LsaQueryInformationPolicy(LSA_HANDLE,POLICY_INFORMATION_CLASS,PVOID*);
 
 NTSTATUS WINAPI LsaFreeMemory(PVOID);
diff --git a/include/winbase.h b/include/winbase.h
index 79c4500..d35dc77 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -1374,12 +1374,15 @@
 LONG        WINAPI InterlockedExchange(LPLONG,LONG);
 LONG        WINAPI InterlockedExchangeAdd(PLONG,LONG);
 LONG        WINAPI InterlockedIncrement(LPLONG);
-BOOL      WINAPI IsDBCSLeadByteEx(UINT,BYTE);
-BOOL      WINAPI IsProcessorFeaturePresent(DWORD);
-BOOL      WINAPI IsValidLocale(DWORD,DWORD);
-BOOL      WINAPI LocalFileTimeToFileTime(const FILETIME*,LPFILETIME);
-BOOL      WINAPI LockFile(HANDLE,DWORD,DWORD,DWORD,DWORD);
-BOOL      WINAPI LockFileEx(HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED);    
+BOOL        WINAPI IsDBCSLeadByteEx(UINT,BYTE);
+BOOL        WINAPI IsProcessorFeaturePresent(DWORD);
+BOOL        WINAPI IsValidLocale(DWORD,DWORD);
+BOOL        WINAPI LookupAccountSidA(LPCSTR,PSID,LPSTR,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE);
+BOOL        WINAPI LookupAccountSidW(LPCWSTR,PSID,LPWSTR,LPDWORD,LPWSTR,LPDWORD,PSID_NAME_USE);
+#define     LookupAccountSid WINELIB_NAME_AW(LookupAccountSidW)
+BOOL        WINAPI LocalFileTimeToFileTime(const FILETIME*,LPFILETIME);
+BOOL        WINAPI LockFile(HANDLE,DWORD,DWORD,DWORD,DWORD);
+BOOL        WINAPI LockFileEx(HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED);    
 BOOL        WINAPI LookupPrivilegeValueA(LPCSTR,LPCSTR,LPVOID);
 BOOL        WINAPI LookupPrivilegeValueW(LPCWSTR,LPCWSTR,LPVOID);
 #define     LookupPrivilegeValue WINELIB_NAME_AW(LookupPrivilegeValue)