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