[ADVAPI32] Sync cred.c with Wine Staging 3.3. CORE-14434
[reactos.git] / dll / win32 / advapi32 / misc / sysfunc.c
index b8fc700..b0ed231 100644 (file)
@@ -1,17 +1,18 @@
 /*
- *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
  * FILE:            dll/win32/advapi32/misc/sysfun.c
  * PURPOSE:         advapi32.dll system functions (undocumented)
  * PROGRAMMER:      Emanuele Aliberti
  * UPDATE HISTORY:
- *     19990413 EA     created
- *     19990415 EA
- *     20080424 Ported from WINE
+ *  19990413 EA created
+ *  19990415 EA
+ *  20080424 Ported from WINE
  */
 
 #include <advapi32.h>
+#include <ntsecapi.h>
+#include <ksecioctl.h>
 #include <md4.h>
 #include <md5.h>
 #include <rc4.h>
@@ -448,8 +449,8 @@ SystemFunction028(INT a, INT b)
 {
     //NDRCContextBinding()
     //SystemFunction034()
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 28;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return 28;
 }
 
 
@@ -462,8 +463,8 @@ WINAPI
 SystemFunction029(INT a, INT b)
 {
     //I_RpcBindingIsClientLocal()
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 29;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return 29;
 }
 
 
@@ -482,7 +483,7 @@ SystemFunction029(INT a, INT b)
 BOOL
 WINAPI SystemFunction030(LPCVOID b1, LPCVOID b2)
 {
-       return !memcmp(b1, b2, 0x10);
+    return !memcmp(b1, b2, 0x10);
 }
 
 
@@ -522,8 +523,8 @@ INT
 WINAPI
 SystemFunction033(INT a, INT b)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 33;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return 33;
 }
 
 /**********************************************************************
@@ -538,8 +539,8 @@ SystemFunction034(INT a, INT b)
     //I_RpcMapWin32Status
     //RpcStringBindingParseW
     //RpcStringFreeW
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 34;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return 34;
 }
 
 
@@ -577,7 +578,7 @@ SystemFunction036(PVOID pbBuffer, ULONG dwLen)
     ////////////////////////////////////////////////////////////////
     //////////////////// B I G   W A R N I N G  !!! ////////////////
     // This function will output numbers based on the tick count. //
-    // It will NOT OUPUT CRYPTOGRAPHIC-SAFE RANDOM NUMBERS !!!    //
+    // It will NOT OUTPUT CRYPTOGRAPHIC-SAFE RANDOM NUMBERS !!!    //
     ////////////////////////////////////////////////////////////////
 
     DWORD dwSeed;
@@ -607,14 +608,101 @@ SystemFunction036(PVOID pbBuffer, ULONG dwLen)
         do
         {
             /* Get each byte from the pseudo random number and store it in the buffer */
-            *pBuffer = (BYTE)(uPseudoRandom >> 8 * (dwLen % 4) & 0xFF);
+            *pBuffer = (BYTE)(uPseudoRandom >> 8 * (dwLen % 3) & 0xFF);
             ++pBuffer;
-        } while(--dwLen % 4);
+        } while(--dwLen % 3);
     } while(dwLen);
 
     return TRUE;
 }
 
+HANDLE KsecDeviceHandle;
+
+static
+NTSTATUS
+KsecOpenDevice()
+{
+    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KsecDD");
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK IoStatusBlock;
+    HANDLE DeviceHandle;
+    NTSTATUS Status;
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &DeviceName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = NtOpenFile(&DeviceHandle,
+                        FILE_READ_DATA | SYNCHRONIZE,
+                        &ObjectAttributes,
+                        &IoStatusBlock,
+                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                        FILE_SYNCHRONOUS_IO_NONALERT);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    if (InterlockedCompareExchangePointer(&KsecDeviceHandle, DeviceHandle, NULL) != NULL)
+    {
+        NtClose(DeviceHandle);
+    }
+
+    return STATUS_SUCCESS;
+}
+
+VOID
+CloseKsecDdHandle(VOID)
+{
+    /* Check if we already opened a handle to ksecdd */
+    if (KsecDeviceHandle != NULL)
+    {
+        /* Close it */
+        CloseHandle(KsecDeviceHandle);
+        KsecDeviceHandle = NULL;
+    }
+}
+
+static
+NTSTATUS
+KsecDeviceIoControl(
+    ULONG IoControlCode,
+    PVOID InputBuffer,
+    SIZE_T InputBufferLength,
+    PVOID OutputBuffer,
+    SIZE_T OutputBufferLength)
+{
+    IO_STATUS_BLOCK IoStatusBlock;
+    NTSTATUS Status;
+
+    /* Check if we already have a handle */
+    if (KsecDeviceHandle == NULL)
+    {
+        /* Try to open the device */
+        Status = KsecOpenDevice();
+        if (!NT_SUCCESS(Status))
+        {
+            //ERR("Failed to open handle to KsecDd driver!\n");
+            return Status;
+        }
+    }
+
+    /* Call the driver */
+    Status = NtDeviceIoControlFile(KsecDeviceHandle,
+                                   NULL,
+                                   NULL,
+                                   NULL,
+                                   &IoStatusBlock,
+                                   IoControlCode,
+                                   InputBuffer,
+                                   InputBufferLength,
+                                   OutputBuffer,
+                                   OutputBufferLength);
+
+    return Status;
+}
+
 /*
    These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory,
    in crypt32.dll.
@@ -642,10 +730,33 @@ SystemFunction036(PVOID pbBuffer, ULONG dwLen)
  *  If flags are specified when encrypting, the same flag value must be given
  *  when decrypting the memory.
  */
-NTSTATUS WINAPI SystemFunction040(PVOID memory, ULONG length, ULONG flags)
+NTSTATUS
+WINAPI
+SystemFunction040(
+    _Inout_ PVOID Memory,
+    _In_ ULONG MemoryLength,
+    _In_ ULONG OptionFlags)
 {
-       //FIXME("(%p, %x, %x): stub [RtlEncryptMemory]\n", memory, length, flags);
-       return STATUS_SUCCESS;
+    ULONG IoControlCode;
+
+    if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS)
+    {
+        IoControlCode = IOCTL_KSEC_ENCRYPT_SAME_PROCESS;
+    }
+    else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
+    {
+        IoControlCode = IOCTL_KSEC_ENCRYPT_CROSS_PROCESS;
+    }
+    else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON)
+    {
+        IoControlCode = IOCTL_KSEC_ENCRYPT_SAME_LOGON;
+    }
+    else
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    return KsecDeviceIoControl(IoControlCode, Memory, MemoryLength, Memory, MemoryLength);
 }
 
 /******************************************************************************
@@ -670,10 +781,33 @@ NTSTATUS WINAPI SystemFunction040(PVOID memory, ULONG length, ULONG flags)
  *  If flags are specified when encrypting, the same flag value must be given
  *  when decrypting the memory.
  */
-NTSTATUS WINAPI SystemFunction041(PVOID memory, ULONG length, ULONG flags)
+NTSTATUS
+WINAPI
+SystemFunction041(
+    _Inout_ PVOID Memory,
+    _In_ ULONG MemoryLength,
+    _In_ ULONG OptionFlags)
 {
-       //FIXME("(%p, %x, %x): stub [RtlDecryptMemory]\n", memory, length, flags);
-       return STATUS_SUCCESS;
+    ULONG IoControlCode;
+
+    if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS)
+    {
+        IoControlCode = IOCTL_KSEC_DECRYPT_SAME_PROCESS;
+    }
+    else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
+    {
+        IoControlCode = IOCTL_KSEC_DECRYPT_CROSS_PROCESS;
+    }
+    else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON)
+    {
+        IoControlCode = IOCTL_KSEC_DECRYPT_SAME_LOGON;
+    }
+    else
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    return KsecDeviceIoControl(IoControlCode, Memory, MemoryLength, Memory, MemoryLength);
 }
 
 /* EOF */