[ADVAPI32] SystemFunction004 and SystemFunction005 must return the required output...
[reactos.git] / dll / win32 / advapi32 / misc / sysfunc.c
index 12713dd..b6bee62 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
+ * FILE:            dll/win32/advapi32/misc/sysfunc.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>
@@ -129,7 +130,10 @@ WINAPI SystemFunction004(const struct ustring *in,
 
     crypt_len = ((in->Length+7)&~7);
     if (out->MaximumLength < (crypt_len+8))
+    {
+        out->Length = crypt_len + 8;
         return STATUS_BUFFER_TOO_SMALL;
+    }
 
     data.ui[0] = in->Length;
     data.ui[1] = 1;
@@ -202,7 +206,10 @@ WINAPI SystemFunction005(const struct ustring *in,
 
     crypt_len = data.ui[0];
     if (crypt_len > out->MaximumLength)
+    {
+        out->Length = crypt_len;
         return STATUS_BUFFER_TOO_SMALL;
+    }
 
     for (ofs=0; (ofs+8)<crypt_len; ofs+=8)
         CRYPT_DESunhash(out->Buffer+ofs, deskey, in->Buffer+ofs+8);
@@ -448,8 +455,8 @@ SystemFunction028(INT a, INT b)
 {
     //NDRCContextBinding()
     //SystemFunction034()
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 28;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return 28;
 }
 
 
@@ -462,8 +469,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 +489,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 +529,8 @@ INT
 WINAPI
 SystemFunction033(INT a, INT b)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 33;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return 33;
 }
 
 /**********************************************************************
@@ -538,8 +545,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 +584,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;
@@ -615,6 +622,93 @@ SystemFunction036(PVOID pbBuffer, ULONG 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 +736,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 +787,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 */