* Sync up to trunk head (r65074).
[reactos.git] / dll / win32 / advapi32 / misc / sysfunc.c
1 /*
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: dll/win32/advapi32/misc/sysfun.c
6 * PURPOSE: advapi32.dll system functions (undocumented)
7 * PROGRAMMER: Emanuele Aliberti
8 * UPDATE HISTORY:
9 * 19990413 EA created
10 * 19990415 EA
11 * 20080424 Ported from WINE
12 */
13
14 #include <advapi32.h>
15 #include <ntsecapi.h>
16 #include <ksecioctl.h>
17 #include <md4.h>
18 #include <md5.h>
19 #include <rc4.h>
20
21 static const unsigned char CRYPT_LMhash_Magic[8] =
22 { 'K', 'G', 'S', '!', '@', '#', '$', '%' };
23
24 /******************************************************************************
25 * SystemFunction001 [ADVAPI32.@]
26 *
27 * Encrypts a single block of data using DES
28 *
29 * PARAMS
30 * data [I] data to encrypt (8 bytes)
31 * key [I] key data (7 bytes)
32 * output [O] the encrypted data (8 bytes)
33 *
34 * RETURNS
35 * Success: STATUS_SUCCESS
36 * Failure: STATUS_UNSUCCESSFUL
37 *
38 */
39 NTSTATUS
40 WINAPI SystemFunction001(const BYTE *data, const BYTE *key, LPBYTE output)
41 {
42 if (!data || !output)
43 return STATUS_UNSUCCESSFUL;
44 CRYPT_DEShash(output, key, data);
45 return STATUS_SUCCESS;
46 }
47
48
49 /******************************************************************************
50 * SystemFunction002 [ADVAPI32.@]
51 *
52 * Decrypts a single block of data using DES
53 *
54 * PARAMS
55 * data [I] data to decrypt (8 bytes)
56 * key [I] key data (7 bytes)
57 * output [O] the decrypted data (8 bytes)
58 *
59 * RETURNS
60 * Success: STATUS_SUCCESS
61 * Failure: STATUS_UNSUCCESSFUL
62 *
63 */
64 NTSTATUS
65 WINAPI SystemFunction002(const BYTE *data, const BYTE *key, LPBYTE output)
66 {
67 if (!data || !output)
68 return STATUS_UNSUCCESSFUL;
69 CRYPT_DESunhash(output, key, data);
70 return STATUS_SUCCESS;
71 }
72
73
74 /******************************************************************************
75 * SystemFunction003 [ADVAPI32.@]
76 *
77 * Hashes a key using DES and a fixed datablock
78 *
79 * PARAMS
80 * key [I] key data (7 bytes)
81 * output [O] hashed key (8 bytes)
82 *
83 * RETURNS
84 * Success: STATUS_SUCCESS
85 * Failure: STATUS_UNSUCCESSFUL
86 *
87 */
88 NTSTATUS
89 WINAPI SystemFunction003(const BYTE *key, LPBYTE output)
90 {
91 if (!output)
92 return STATUS_UNSUCCESSFUL;
93 CRYPT_DEShash(output, key, CRYPT_LMhash_Magic);
94 return STATUS_SUCCESS;
95 }
96
97
98 /******************************************************************************
99 * SystemFunction004 [ADVAPI32.@]
100 *
101 * Encrypts a block of data with DES in ECB mode, preserving the length
102 *
103 * PARAMS
104 * data [I] data to encrypt
105 * key [I] key data (up to 7 bytes)
106 * output [O] buffer to receive encrypted data
107 *
108 * RETURNS
109 * Success: STATUS_SUCCESS
110 * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small
111 * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length
112 *
113 * NOTES
114 * Encrypt buffer size should be input size rounded up to 8 bytes
115 * plus an extra 8 bytes.
116 */
117 NTSTATUS
118 WINAPI SystemFunction004(const struct ustring *in,
119 const struct ustring *key,
120 struct ustring *out)
121 {
122 union {
123 unsigned char uc[8];
124 unsigned int ui[2];
125 } data;
126 unsigned char deskey[7];
127 unsigned int crypt_len, ofs;
128
129 if (key->Length<=0)
130 return STATUS_INVALID_PARAMETER_2;
131
132 crypt_len = ((in->Length+7)&~7);
133 if (out->MaximumLength < (crypt_len+8))
134 return STATUS_BUFFER_TOO_SMALL;
135
136 data.ui[0] = in->Length;
137 data.ui[1] = 1;
138
139 if (key->Length<sizeof deskey)
140 {
141 memset(deskey, 0, sizeof deskey);
142 memcpy(deskey, key->Buffer, key->Length);
143 }
144 else
145 memcpy(deskey, key->Buffer, sizeof deskey);
146
147 CRYPT_DEShash(out->Buffer, deskey, data.uc);
148
149 for(ofs=0; ofs<(crypt_len-8); ofs+=8)
150 CRYPT_DEShash(out->Buffer+8+ofs, deskey, in->Buffer+ofs);
151
152 memset(data.uc, 0, sizeof data.uc);
153 memcpy(data.uc, in->Buffer+ofs, in->Length +8-crypt_len);
154 CRYPT_DEShash(out->Buffer+8+ofs, deskey, data.uc);
155
156 out->Length = crypt_len+8;
157
158 return STATUS_SUCCESS;
159 }
160
161 /******************************************************************************
162 * SystemFunction005 [ADVAPI32.@]
163 *
164 * Decrypts a block of data with DES in ECB mode
165 *
166 * PARAMS
167 * data [I] data to decrypt
168 * key [I] key data (up to 7 bytes)
169 * output [O] buffer to receive decrypted data
170 *
171 * RETURNS
172 * Success: STATUS_SUCCESS
173 * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small
174 * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length
175 *
176 */
177 NTSTATUS
178 WINAPI SystemFunction005(const struct ustring *in,
179 const struct ustring *key,
180 struct ustring *out)
181 {
182 union {
183 unsigned char uc[8];
184 unsigned int ui[2];
185 } data;
186 unsigned char deskey[7];
187 unsigned int ofs, crypt_len;
188
189 if (key->Length<=0)
190 return STATUS_INVALID_PARAMETER_2;
191
192 if (key->Length<sizeof deskey)
193 {
194 memset(deskey, 0, sizeof deskey);
195 memcpy(deskey, key->Buffer, key->Length);
196 }
197 else
198 memcpy(deskey, key->Buffer, sizeof deskey);
199
200 CRYPT_DESunhash(data.uc, deskey, in->Buffer);
201
202 if (data.ui[1] != 1)
203 return STATUS_UNKNOWN_REVISION;
204
205 crypt_len = data.ui[0];
206 if (crypt_len > out->MaximumLength)
207 return STATUS_BUFFER_TOO_SMALL;
208
209 for (ofs=0; (ofs+8)<crypt_len; ofs+=8)
210 CRYPT_DESunhash(out->Buffer+ofs, deskey, in->Buffer+ofs+8);
211
212 if (ofs<crypt_len)
213 {
214 CRYPT_DESunhash(data.uc, deskey, in->Buffer+ofs+8);
215 memcpy(out->Buffer+ofs, data.uc, crypt_len-ofs);
216 }
217
218 out->Length = crypt_len;
219
220 return STATUS_SUCCESS;
221 }
222
223 /******************************************************************************
224 * SystemFunction007 [ADVAPI32.@]
225 *
226 * MD4 hash a unicode string
227 *
228 * PARAMS
229 * string [I] the string to hash
230 * output [O] the md4 hash of the string (16 bytes)
231 *
232 * RETURNS
233 * Success: STATUS_SUCCESS
234 * Failure: STATUS_UNSUCCESSFUL
235 *
236 */
237 NTSTATUS
238 WINAPI SystemFunction007(const UNICODE_STRING *string, LPBYTE hash)
239 {
240 MD4_CTX ctx;
241
242 MD4Init( &ctx );
243 MD4Update( &ctx, (const BYTE *)string->Buffer, string->Length );
244 MD4Final( &ctx );
245 memcpy( hash, ctx.digest, 0x10 );
246
247 return STATUS_SUCCESS;
248 }
249
250 /******************************************************************************
251 * SystemFunction008 [ADVAPI32.@]
252 *
253 * Creates a LM response from a challenge and a password hash
254 *
255 * PARAMS
256 * challenge [I] Challenge from authentication server
257 * hash [I] NTLM hash (from SystemFunction006)
258 * response [O] response to send back to the server
259 *
260 * RETURNS
261 * Success: STATUS_SUCCESS
262 * Failure: STATUS_UNSUCCESSFUL
263 *
264 * NOTES
265 * see http://davenport.sourceforge.net/ntlm.html#theLmResponse
266 *
267 */
268 NTSTATUS
269 WINAPI SystemFunction008(const BYTE *challenge, const BYTE *hash, LPBYTE response)
270 {
271 BYTE key[7*3];
272
273 if (!challenge || !response)
274 return STATUS_UNSUCCESSFUL;
275
276 memset(key, 0, sizeof key);
277 memcpy(key, hash, 0x10);
278
279 CRYPT_DEShash(response, key, challenge);
280 CRYPT_DEShash(response+8, key+7, challenge);
281 CRYPT_DEShash(response+16, key+14, challenge);
282
283 return STATUS_SUCCESS;
284 }
285
286 /******************************************************************************
287 * SystemFunction009 [ADVAPI32.@]
288 *
289 * Seems to do the same as SystemFunction008...
290 */
291 NTSTATUS
292 WINAPI SystemFunction009(const BYTE *challenge, const BYTE *hash, LPBYTE response)
293 {
294 return SystemFunction008(challenge, hash, response);
295 }
296
297 /******************************************************************************
298 * SystemFunction010 [ADVAPI32.@]
299 * SystemFunction011 [ADVAPI32.@]
300 *
301 * MD4 hashes 16 bytes of data
302 *
303 * PARAMS
304 * unknown [] seems to have no effect on the output
305 * data [I] pointer to data to hash (16 bytes)
306 * output [O] the md4 hash of the data (16 bytes)
307 *
308 * RETURNS
309 * Success: STATUS_SUCCESS
310 * Failure: STATUS_UNSUCCESSFUL
311 *
312 */
313 NTSTATUS
314 WINAPI SystemFunction010(LPVOID unknown, const BYTE *data, LPBYTE hash)
315 {
316 MD4_CTX ctx;
317
318 MD4Init( &ctx );
319 MD4Update( &ctx, data, 0x10 );
320 MD4Final( &ctx );
321 memcpy( hash, ctx.digest, 0x10 );
322
323 return STATUS_SUCCESS;
324 }
325
326 /******************************************************************************
327 * SystemFunction012 [ADVAPI32.@]
328 * SystemFunction014 [ADVAPI32.@]
329 * SystemFunction016 [ADVAPI32.@]
330 * SystemFunction018 [ADVAPI32.@]
331 * SystemFunction020 [ADVAPI32.@]
332 * SystemFunction022 [ADVAPI32.@]
333 *
334 * Encrypts two DES blocks with two keys
335 *
336 * PARAMS
337 * data [I] data to encrypt (16 bytes)
338 * key [I] key data (two lots of 7 bytes)
339 * output [O] buffer to receive encrypted data (16 bytes)
340 *
341 * RETURNS
342 * Success: STATUS_SUCCESS
343 * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL
344 */
345 NTSTATUS
346 WINAPI SystemFunction012(const BYTE *in, const BYTE *key, LPBYTE out)
347 {
348 if (!in || !out)
349 return STATUS_UNSUCCESSFUL;
350
351 CRYPT_DEShash(out, key, in);
352 CRYPT_DEShash(out+8, key+7, in+8);
353 return STATUS_SUCCESS;
354 }
355
356 /******************************************************************************
357 * SystemFunction013 [ADVAPI32.@]
358 * SystemFunction015 [ADVAPI32.@]
359 * SystemFunction017 [ADVAPI32.@]
360 * SystemFunction019 [ADVAPI32.@]
361 * SystemFunction021 [ADVAPI32.@]
362 * SystemFunction023 [ADVAPI32.@]
363 *
364 * Decrypts two DES blocks with two keys
365 *
366 * PARAMS
367 * data [I] data to decrypt (16 bytes)
368 * key [I] key data (two lots of 7 bytes)
369 * output [O] buffer to receive decrypted data (16 bytes)
370 *
371 * RETURNS
372 * Success: STATUS_SUCCESS
373 * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL
374 */
375 NTSTATUS
376 WINAPI SystemFunction013(const BYTE *in, const BYTE *key, LPBYTE out)
377 {
378 if (!in || !out)
379 return STATUS_UNSUCCESSFUL;
380 CRYPT_DESunhash(out, key, in);
381 CRYPT_DESunhash(out+8, key+7, in+8);
382 return STATUS_SUCCESS;
383 }
384
385 /******************************************************************************
386 * SystemFunction024 [ADVAPI32.@]
387 *
388 * Encrypts two DES blocks with a 32 bit key...
389 *
390 * PARAMS
391 * data [I] data to encrypt (16 bytes)
392 * key [I] key data (4 bytes)
393 * output [O] buffer to receive encrypted data (16 bytes)
394 *
395 * RETURNS
396 * Success: STATUS_SUCCESS
397 */
398 NTSTATUS
399 WINAPI SystemFunction024(const BYTE *in, const BYTE *key, LPBYTE out)
400 {
401 BYTE deskey[0x10];
402
403 memcpy(deskey, key, 4);
404 memcpy(deskey+4, key, 4);
405 memcpy(deskey+8, key, 4);
406 memcpy(deskey+12, key, 4);
407
408 CRYPT_DEShash(out, deskey, in);
409 CRYPT_DEShash(out+8, deskey+7, in+8);
410
411 return STATUS_SUCCESS;
412 }
413
414 /******************************************************************************
415 * SystemFunction025 [ADVAPI32.@]
416 *
417 * Decrypts two DES blocks with a 32 bit key...
418 *
419 * PARAMS
420 * data [I] data to encrypt (16 bytes)
421 * key [I] key data (4 bytes)
422 * output [O] buffer to receive encrypted data (16 bytes)
423 *
424 * RETURNS
425 * Success: STATUS_SUCCESS
426 */
427 NTSTATUS
428 WINAPI SystemFunction025(const BYTE *in, const BYTE *key, LPBYTE out)
429 {
430 BYTE deskey[0x10];
431
432 memcpy(deskey, key, 4);
433 memcpy(deskey+4, key, 4);
434 memcpy(deskey+8, key, 4);
435 memcpy(deskey+12, key, 4);
436
437 CRYPT_DESunhash(out, deskey, in);
438 CRYPT_DESunhash(out+8, deskey+7, in+8);
439
440 return STATUS_SUCCESS;
441 }
442
443 /**********************************************************************
444 *
445 * @unimplemented
446 */
447 INT
448 WINAPI
449 SystemFunction028(INT a, INT b)
450 {
451 //NDRCContextBinding()
452 //SystemFunction034()
453 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
454 return 28;
455 }
456
457
458 /**********************************************************************
459 *
460 * @unimplemented
461 */
462 INT
463 WINAPI
464 SystemFunction029(INT a, INT b)
465 {
466 //I_RpcBindingIsClientLocal()
467 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
468 return 29;
469 }
470
471
472 /******************************************************************************
473 * SystemFunction030 (ADVAPI32.@)
474 *
475 * Tests if two blocks of 16 bytes are equal
476 *
477 * PARAMS
478 * b1,b2 [I] block of 16 bytes
479 *
480 * RETURNS
481 * TRUE if blocks are the same
482 * FALSE if blocks are different
483 */
484 BOOL
485 WINAPI SystemFunction030(LPCVOID b1, LPCVOID b2)
486 {
487 return !memcmp(b1, b2, 0x10);
488 }
489
490
491 /******************************************************************************
492 * SystemFunction032 [ADVAPI32.@]
493 *
494 * Encrypts a string data using ARC4
495 *
496 * PARAMS
497 * data [I/O] data to encrypt
498 * key [I] key data
499 *
500 * RETURNS
501 * Success: STATUS_SUCCESS
502 * Failure: STATUS_UNSUCCESSFUL
503 *
504 * NOTES
505 * see http://web.it.kth.se/~rom/ntsec.html#crypto-strongavail
506 */
507 NTSTATUS
508 WINAPI SystemFunction032(struct ustring *data, const struct ustring *key)
509 {
510 RC4_CONTEXT a4i;
511
512 rc4_init(&a4i, key->Buffer, key->Length);
513 rc4_crypt(&a4i, data->Buffer, data->Length);
514
515 return STATUS_SUCCESS;
516 }
517
518
519 /**********************************************************************
520 *
521 * @unimplemented
522 */
523 INT
524 WINAPI
525 SystemFunction033(INT a, INT b)
526 {
527 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
528 return 33;
529 }
530
531 /**********************************************************************
532 *
533 * @unimplemented
534 */
535 INT
536 WINAPI
537 SystemFunction034(INT a, INT b)
538 {
539 //RpcBindingToStringBindingW
540 //I_RpcMapWin32Status
541 //RpcStringBindingParseW
542 //RpcStringFreeW
543 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
544 return 34;
545 }
546
547
548 /******************************************************************************
549 * SystemFunction035 (ADVAPI32.@)
550 *
551 * Described here:
552 http://disc.server.com/discussion.cgi?disc=148775;article=942;title=Coding%2FASM%2FSystem
553 *
554 * NOTES
555 * Stub, always return TRUE.
556 */
557 BOOL WINAPI SystemFunction035(LPCSTR lpszDllFilePath)
558 {
559 //FIXME("%s: stub\n", debugstr_a(lpszDllFilePath));
560 return TRUE;
561 }
562
563 /******************************************************************************
564 * SystemFunction036 (ADVAPI32.@)
565 *
566 * MSDN documents this function as RtlGenRandom and declares it in ntsecapi.h
567 *
568 * PARAMS
569 * pbBuffer [O] Pointer to memory to receive random bytes.
570 * dwLen [I] Number of random bytes to fetch.
571 *
572 * RETURNS
573 * Always TRUE in my tests
574 */
575 BOOLEAN
576 WINAPI
577 SystemFunction036(PVOID pbBuffer, ULONG dwLen)
578 {
579 ////////////////////////////////////////////////////////////////
580 //////////////////// B I G W A R N I N G !!! ////////////////
581 // This function will output numbers based on the tick count. //
582 // It will NOT OUPUT CRYPTOGRAPHIC-SAFE RANDOM NUMBERS !!! //
583 ////////////////////////////////////////////////////////////////
584
585 DWORD dwSeed;
586 PBYTE pBuffer;
587 ULONG uPseudoRandom;
588 LARGE_INTEGER time;
589 static ULONG uCounter = 17;
590
591 if(!pbBuffer || !dwLen)
592 {
593 /* This function always returns TRUE, even if invalid parameters were passed. (verified under WinXP SP2) */
594 return TRUE;
595 }
596
597 /* Get the first seed from the performance counter */
598 QueryPerformanceCounter(&time);
599 dwSeed = time.LowPart ^ time.HighPart ^ RtlUlongByteSwap(uCounter++);
600
601 /* We will access the buffer bytewise */
602 pBuffer = (PBYTE)pbBuffer;
603
604 do
605 {
606 /* Use the pseudo random number generator RtlRandom, which outputs a 4-byte value and a new seed */
607 uPseudoRandom = RtlRandom(&dwSeed);
608
609 do
610 {
611 /* Get each byte from the pseudo random number and store it in the buffer */
612 *pBuffer = (BYTE)(uPseudoRandom >> 8 * (dwLen % 3) & 0xFF);
613 ++pBuffer;
614 } while(--dwLen % 3);
615 } while(dwLen);
616
617 return TRUE;
618 }
619
620 HANDLE KsecDeviceHandle;
621
622 static
623 NTSTATUS
624 KsecOpenDevice()
625 {
626 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KsecDD");
627 OBJECT_ATTRIBUTES ObjectAttributes;
628 IO_STATUS_BLOCK IoStatusBlock;
629 HANDLE DeviceHandle;
630 NTSTATUS Status;
631
632 InitializeObjectAttributes(&ObjectAttributes,
633 &DeviceName,
634 OBJ_CASE_INSENSITIVE,
635 NULL,
636 NULL);
637 Status = NtOpenFile(&DeviceHandle,
638 FILE_READ_DATA | SYNCHRONIZE,
639 &ObjectAttributes,
640 &IoStatusBlock,
641 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
642 FILE_SYNCHRONOUS_IO_NONALERT);
643 if (!NT_SUCCESS(Status))
644 {
645 return Status;
646 }
647
648 if (InterlockedCompareExchangePointer(&KsecDeviceHandle, DeviceHandle, NULL) != NULL)
649 {
650 NtClose(DeviceHandle);
651 }
652
653 return STATUS_SUCCESS;
654 }
655
656 VOID
657 CloseKsecDdHandle(VOID)
658 {
659 /* Check if we already opened a handle to ksecdd */
660 if (KsecDeviceHandle != NULL)
661 {
662 /* Close it */
663 CloseHandle(KsecDeviceHandle);
664 KsecDeviceHandle = NULL;
665 }
666 }
667
668 static
669 NTSTATUS
670 KsecDeviceIoControl(
671 ULONG IoControlCode,
672 PVOID InputBuffer,
673 SIZE_T InputBufferLength,
674 PVOID OutputBuffer,
675 SIZE_T OutputBufferLength)
676 {
677 IO_STATUS_BLOCK IoStatusBlock;
678 NTSTATUS Status;
679
680 /* Check if we already have a handle */
681 if (KsecDeviceHandle == NULL)
682 {
683 /* Try to open the device */
684 Status = KsecOpenDevice();
685 if (!NT_SUCCESS(Status))
686 {
687 //ERR("Failed to open handle to KsecDd driver!\n");
688 return Status;
689 }
690 }
691
692 /* Call the driver */
693 Status = NtDeviceIoControlFile(KsecDeviceHandle,
694 NULL,
695 NULL,
696 NULL,
697 &IoStatusBlock,
698 IoControlCode,
699 InputBuffer,
700 InputBufferLength,
701 OutputBuffer,
702 OutputBufferLength);
703
704 return Status;
705 }
706
707 /*
708 These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory,
709 in crypt32.dll.
710 */
711
712 /******************************************************************************
713 * SystemFunction040 (ADVAPI32.@)
714 *
715 * MSDN documents this function as RtlEncryptMemory and declares it in ntsecapi.h.
716 *
717 * PARAMS
718 * memory [I/O] Pointer to memory to encrypt.
719 * length [I] Length of region to encrypt in bytes.
720 * flags [I] Control whether other processes are able to decrypt the memory.
721 * RTL_ENCRYPT_OPTION_SAME_PROCESS
722 * RTL_ENCRYPT_OPTION_CROSS_PROCESS
723 * RTL_ENCRYPT_OPTION_SAME_LOGON
724 *
725 * RETURNS
726 * Success: STATUS_SUCCESS
727 * Failure: NTSTATUS error code
728 *
729 * NOTES
730 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE.
731 * If flags are specified when encrypting, the same flag value must be given
732 * when decrypting the memory.
733 */
734 NTSTATUS
735 WINAPI
736 SystemFunction040(
737 _Inout_ PVOID Memory,
738 _In_ ULONG MemoryLength,
739 _In_ ULONG OptionFlags)
740 {
741 ULONG IoControlCode;
742
743 if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS)
744 {
745 IoControlCode = IOCTL_KSEC_ENCRYPT_SAME_PROCESS;
746 }
747 else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
748 {
749 IoControlCode = IOCTL_KSEC_ENCRYPT_CROSS_PROCESS;
750 }
751 else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON)
752 {
753 IoControlCode = IOCTL_KSEC_ENCRYPT_SAME_LOGON;
754 }
755 else
756 {
757 return STATUS_INVALID_PARAMETER;
758 }
759
760 return KsecDeviceIoControl(IoControlCode, Memory, MemoryLength, Memory, MemoryLength);
761 }
762
763 /******************************************************************************
764 * SystemFunction041 (ADVAPI32.@)
765 *
766 * MSDN documents this function as RtlDecryptMemory and declares it in ntsecapi.h.
767 *
768 * PARAMS
769 * memory [I/O] Pointer to memory to decrypt.
770 * length [I] Length of region to decrypt in bytes.
771 * flags [I] Control whether other processes are able to decrypt the memory.
772 * RTL_ENCRYPT_OPTION_SAME_PROCESS
773 * RTL_ENCRYPT_OPTION_CROSS_PROCESS
774 * RTL_ENCRYPT_OPTION_SAME_LOGON
775 *
776 * RETURNS
777 * Success: STATUS_SUCCESS
778 * Failure: NTSTATUS error code
779 *
780 * NOTES
781 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE.
782 * If flags are specified when encrypting, the same flag value must be given
783 * when decrypting the memory.
784 */
785 NTSTATUS
786 WINAPI
787 SystemFunction041(
788 _Inout_ PVOID Memory,
789 _In_ ULONG MemoryLength,
790 _In_ ULONG OptionFlags)
791 {
792 ULONG IoControlCode;
793
794 if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS)
795 {
796 IoControlCode = IOCTL_KSEC_DECRYPT_SAME_PROCESS;
797 }
798 else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS)
799 {
800 IoControlCode = IOCTL_KSEC_DECRYPT_CROSS_PROCESS;
801 }
802 else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON)
803 {
804 IoControlCode = IOCTL_KSEC_DECRYPT_SAME_LOGON;
805 }
806 else
807 {
808 return STATUS_INVALID_PARAMETER;
809 }
810
811 return KsecDeviceIoControl(IoControlCode, Memory, MemoryLength, Memory, MemoryLength);
812 }
813
814 /* EOF */