ReactOS 0.4.17-dev-116-ga4b6fe9
rxact.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Runtime Library (RTL)
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Registry Transaction API
5 * COPYRIGHT: Copyright 2014 Timo Kreuzer <timo.kreuzer@reactos.org>
6 */
7
8/* INCLUDES *****************************************************************/
9
10#include <rtl.h>
11#include <ndk/cmfuncs.h>
12
13#define NDEBUG
14#include <debug.h>
15
16#define RXACT_DEFAULT_BUFFER_SIZE (4 * PAGE_SIZE)
17
18typedef struct _RXACT_INFO
19{
24
25typedef struct _RXACT_DATA
26{
31
32typedef struct _RXACT_CONTEXT
33{
39
40typedef struct _RXACT_ACTION
41{
51
52enum
53{
56};
57
58/* FUNCTIONS *****************************************************************/
59
60static
61VOID
67{
68 Context->Data = NULL;
69 Context->RootDirectory = RootDirectory;
70 Context->CanUseHandles = TRUE;
71 Context->KeyHandle = KeyHandle;
72}
73
74static
79 ULONG ActionType,
82{
86
87 /* Check what kind of action this is */
88 if (ActionType == RXactDeleteKey)
89 {
90 /* This is a delete, so open the key for delete */
92 KeyName,
95 NULL);
97 }
98 else if (ActionType == RXactSetValueKey)
99 {
100 /* This is a create, so open or create with write access */
102 KeyName,
105 NULL);
106 Status = ZwCreateKey(KeyHandle,
107 KEY_WRITE,
109 0,
110 NULL,
111 0,
112 &Disposition);
113 }
114 else
115 {
117 }
118
119 return Status;
120}
121
122static
124NTAPI
127{
130 NTSTATUS Status, TmpStatus;
132 ULONG i;
133
134 Data = Context->Data;
135
136 /* The first action record starts after the data header */
137 Action = (PRXACT_ACTION)(Data + 1);
138
139 /* Loop all recorded actions */
140 for (i = 0; i < Data->ActionCount; i++)
141 {
142 /* Translate relative offsets to actual pointers */
143 Action->KeyName.Buffer = (PWSTR)((PUCHAR)Data + (ULONG_PTR)Action->KeyName.Buffer);
144 Action->ValueName.Buffer = (PWSTR)((PUCHAR)Data + (ULONG_PTR)Action->ValueName.Buffer);
145 Action->ValueData = (PUCHAR)Data + (ULONG_PTR)Action->ValueData;
146
147 /* Check what kind of action this is */
148 if (Action->Type == RXactDeleteKey)
149 {
150 /* This is a delete action. Check if we can use a handle */
151 if ((Action->KeyHandle != INVALID_HANDLE_VALUE) && Context->CanUseHandles)
152 {
153 /* Delete the key by the given handle */
154 Status = ZwDeleteKey(Action->KeyHandle);
155 if (!NT_SUCCESS(Status))
156 {
157 return Status;
158 }
159 }
160 else
161 {
162 /* We cannot use a handle, open the key first by it's name */
163 Status = RXactpOpenTargetKey(Context->RootDirectory,
165 &Action->KeyName,
166 &KeyHandle);
167 if (NT_SUCCESS(Status))
168 {
169 Status = ZwDeleteKey(KeyHandle);
170 TmpStatus = NtClose(KeyHandle);
171 ASSERT(NT_SUCCESS(TmpStatus));
172 if (!NT_SUCCESS(Status))
173 {
174 return Status;
175 }
176 }
177 else
178 {
179 /* Failed to open the key, it's ok, if it was not found */
181 return Status;
182 }
183 }
184 }
185 else if (Action->Type == RXactSetValueKey)
186 {
187 /* This is a set action. Check if we can use a handle */
188 if ((Action->KeyHandle != INVALID_HANDLE_VALUE) && Context->CanUseHandles)
189 {
190 /* Set the key value using the given key handle */
191 Status = ZwSetValueKey(Action->KeyHandle,
192 &Action->ValueName,
193 0,
194 Action->ValueType,
195 Action->ValueData,
196 Action->ValueDataSize);
197 if (!NT_SUCCESS(Status))
198 {
199 return Status;
200 }
201 }
202 else
203 {
204 /* We cannot use a handle, open the key first by it's name */
205 Status = RXactpOpenTargetKey(Context->RootDirectory,
207 &Action->KeyName,
208 &KeyHandle);
209 if (!NT_SUCCESS(Status))
210 {
211 return Status;
212 }
213
214 /* Set the key value */
215 Status = ZwSetValueKey(KeyHandle,
216 &Action->ValueName,
217 0,
218 Action->ValueType,
219 Action->ValueData,
220 Action->ValueDataSize);
221
222 TmpStatus = NtClose(KeyHandle);
223 ASSERT(NT_SUCCESS(TmpStatus));
224
225 if (!NT_SUCCESS(Status))
226 {
227 return Status;
228 }
229 }
230 }
231 else
232 {
233 ASSERT(FALSE);
235 }
236
237 /* Go to the next action record */
239 }
240
241 return STATUS_SUCCESS;
242}
243
245NTAPI
248{
250
251 /* We must not have a buffer yet */
252 if (Context->Data != NULL)
253 {
255 }
256
257 /* Allocate a buffer */
258 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, RXACT_DEFAULT_BUFFER_SIZE);
259 if (Buffer == NULL)
260 {
261 return STATUS_NO_MEMORY;
262 }
263
264 /* Initialize the buffer */
265 Buffer->ActionCount = 0;
266 Buffer->BufferSize = RXACT_DEFAULT_BUFFER_SIZE;
267 Buffer->CurrentSize = sizeof(RXACT_DATA);
268 Context->Data = Buffer;
269
270 return STATUS_SUCCESS;
271}
272
274NTAPI
277{
278 /* We must have a data buffer */
279 if (Context->Data == NULL)
280 {
282 }
283
284 /* Free the buffer */
285 RtlFreeHeap(RtlGetProcessHeap(), 0, Context->Data);
286
287 /* Reinitialize the context */
288 RXactInitializeContext(Context, Context->RootDirectory, Context->KeyHandle);
289
290 return STATUS_SUCCESS;
291}
292
294NTAPI
297 BOOLEAN Commit,
298 PRXACT_CONTEXT *OutContext)
299{
300 NTSTATUS Status, TmpStatus;
302 PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
303 KEY_VALUE_BASIC_INFORMATION KeyValueBasicInfo;
307 RXACT_INFO TransactionInfo;
310 ULONG ValueDataLength;
313
314 /* Open or create the 'RXACT' key in the root directory */
317 &KeyName,
320 NULL);
321 Status = ZwCreateKey(&KeyHandle,
324 0,
325 NULL,
326 0,
327 &Disposition);
328 if (!NT_SUCCESS(Status))
329 {
330 return Status;
331 }
332
333 /* Allocate a new context */
334 Context = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Context));
335 *OutContext = Context;
336 if (Context == NULL)
337 {
338 TmpStatus = ZwDeleteKey(KeyHandle);
339 ASSERT(NT_SUCCESS(TmpStatus));
340
341 TmpStatus = NtClose(KeyHandle);
342 ASSERT(NT_SUCCESS(TmpStatus));
343
344 return STATUS_NO_MEMORY;
345 }
346
347 /* Initialize the context */
349
350 /* Check if we created a new key */
352 {
353 /* The key is new, set the default value */
354 TransactionInfo.Revision = 1;
356 Status = ZwSetValueKey(KeyHandle,
357 &ValueName,
358 0,
359 REG_NONE,
360 &TransactionInfo,
361 sizeof(TransactionInfo));
362 if (!NT_SUCCESS(Status))
363 {
364 TmpStatus = ZwDeleteKey(KeyHandle);
365 ASSERT(NT_SUCCESS(TmpStatus));
366
367 TmpStatus = NtClose(KeyHandle);
368 ASSERT(NT_SUCCESS(TmpStatus));
369
370 RtlFreeHeap(RtlGetProcessHeap(), 0, *OutContext);
371 return Status;
372 }
373
375 }
376 else
377 {
378 /* The key exited, get the default key value */
379 ValueDataLength = sizeof(TransactionInfo);
381 &ValueType,
382 &TransactionInfo,
383 &ValueDataLength,
384 0);
385 if (!NT_SUCCESS(Status))
386 {
387 TmpStatus = NtClose(KeyHandle);
388 ASSERT(NT_SUCCESS(TmpStatus));
389 RtlFreeHeap(RtlGetProcessHeap(), 0, Context);
390 return Status;
391 }
392
393 /* Check if the value date is valid */
394 if ((ValueDataLength != sizeof(TransactionInfo)) ||
395 (TransactionInfo.Revision != 1))
396 {
397 TmpStatus = NtClose(KeyHandle);
398 ASSERT(NT_SUCCESS(TmpStatus));
399 RtlFreeHeap(RtlGetProcessHeap(), 0, Context);
401 }
402
403 /* Query the 'Log' key value */
405 Status = ZwQueryValueKey(KeyHandle,
406 &ValueName,
408 &KeyValueBasicInfo,
409 sizeof(KeyValueBasicInfo),
410 &Length);
411 if (!NT_SUCCESS(Status))
412 {
413 /* There is no 'Log', so we are done */
414 return STATUS_SUCCESS;
415 }
416
417 /* Check if the caller asked to commit the current state */
418 if (!Commit)
419 {
420 /* We have a log, that must be committed first! */
422 }
423
424 /* Query the size of the 'Log' key value */
425 Status = ZwQueryValueKey(KeyHandle,
426 &ValueName,
428 NULL,
429 0,
430 &Length);
432 {
433 return Status;
434 }
435
436 /* Allocate a buffer for the key value information */
437 KeyValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
438 if (KeyValueInformation == NULL)
439 {
440 return STATUS_NO_MEMORY;
441 }
442
443 /* Query the 'Log' key value */
444 Status = ZwQueryValueKey(KeyHandle,
445 &ValueName,
447 KeyValueInformation,
448 Length,
449 &Length);
450 if (!NT_SUCCESS(Status))
451 {
452 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyValueInformation);
453 RtlFreeHeap(RtlGetProcessHeap(), 0, Context);
454 return Status;
455 }
456
457 /* Set the Data pointer to the key value data */
458 Context->Data = (PRXACT_DATA)((PUCHAR)KeyValueInformation +
459 KeyValueInformation->DataOffset);
460
461 /* This is an old log, don't use handles when committing! */
462 Context->CanUseHandles = FALSE;
463
464 /* Commit the data */
466 if (!NT_SUCCESS(Status))
467 {
468 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyValueInformation);
469 RtlFreeHeap(RtlGetProcessHeap(), 0, Context);
470 return Status;
471 }
472
473 /* Delete the old key */
476
477 /* Set the data member to the allocated buffer, so it will get freed */
478 Context->Data = (PRXACT_DATA)KeyValueInformation;
479
480 /* Abort the old transaction */
483
484 return Status;
485 }
486}
487
489NTAPI
492 ULONG ActionType,
498 ULONG ValueDataSize)
499{
500 ULONG ActionSize;
503 ULONG CurrentOffset;
504 PRXACT_DATA NewData;
506
507 /* Validate ActionType parameter */
508 if ((ActionType != RXactDeleteKey) && (ActionType != RXactSetValueKey))
509 {
511 }
512
513 /* Calculate the size of the new action record */
514 ActionSize = ALIGN_UP_BY(ValueName->Length, sizeof(ULONG)) +
515 ALIGN_UP_BY(ValueDataSize, sizeof(ULONG)) +
516 ALIGN_UP_BY(KeyName->Length, sizeof(ULONG)) +
517 ALIGN_UP_BY(sizeof(RXACT_ACTION), sizeof(ULONG));
518
519 /* Calculate the new buffer size we need */
520 RequiredSize = ActionSize + Context->Data->CurrentSize;
521
522 /* Check for integer overflow */
523 if (RequiredSize < ActionSize)
524 {
525 return STATUS_NO_MEMORY;
526 }
527
528 /* Check if the buffer is large enough */
529 BufferSize = Context->Data->BufferSize;
531 {
532 /* Increase by a factor of 2, until it is large enough */
533 while (BufferSize < RequiredSize)
534 {
535 BufferSize *= 2;
536 }
537
538 /* Allocate a new buffer from the heap */
539 NewData = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
540 if (NewData == NULL)
541 {
542 return STATUS_NO_MEMORY;
543 }
544
545 /* Copy the old buffer to the new one */
546 RtlCopyMemory(NewData, Context->Data, Context->Data->CurrentSize);
547
548 /* Free the old buffer and use the new one */
549 RtlFreeHeap(RtlGetProcessHeap(), 0, Context->Data);
550 Context->Data = NewData;
551 NewData->BufferSize = BufferSize;
552 }
553
554 /* Get the next action record */
555 Action = (RXACT_ACTION *)((PUCHAR)Context->Data + Context->Data->CurrentSize);
556
557 /* Fill in the fields */
558 Action->Size = ActionSize;
559 Action->Type = ActionType;
560 Action->KeyName = *KeyName;
561 Action->ValueName = *ValueName;
562 Action->ValueType = ValueType;
563 Action->ValueDataSize = ValueDataSize;
564 Action->KeyHandle = KeyHandle;
565
566 /* Copy the key name (and convert the pointer to a buffer offset) */
567 CurrentOffset = Context->Data->CurrentSize + sizeof(RXACT_ACTION);
568 Action->KeyName.Buffer = UlongToPtr(CurrentOffset);
569 RtlCopyMemory((PUCHAR)Context->Data + CurrentOffset,
570 KeyName->Buffer,
571 KeyName->Length);
572
573 /* Copy the value name (and convert the pointer to a buffer offset) */
574 CurrentOffset += ALIGN_UP_BY(KeyName->Length, sizeof(ULONG));
575 Action->ValueName.Buffer = UlongToPtr(CurrentOffset);
576 RtlCopyMemory((PUCHAR)Context->Data + CurrentOffset,
577 ValueName->Buffer,
578 ValueName->Length);
579
580 /* Update the offset */
581 CurrentOffset += ALIGN_UP_BY(ValueName->Length, sizeof(ULONG));
582
583 /* Is this a set action? */
584 if (ActionType == RXactSetValueKey)
585 {
586 /* Copy the key value data as well */
587 Action->ValueData = UlongToPtr(CurrentOffset);
588 RtlCopyMemory((PUCHAR)Context->Data + CurrentOffset,
589 ValueData,
590 ValueDataSize);
591 CurrentOffset += ALIGN_UP_BY(ValueDataSize, sizeof(ULONG));
592 }
593
594 /* Update data site and action count */
595 Context->Data->CurrentSize = CurrentOffset;
596 Context->Data->ActionCount++;
597
598 return STATUS_SUCCESS;
599}
600
602NTAPI
605 ULONG ActionType,
609 ULONG ValueDataSize)
610{
612
613 /* Create a key and set the default key value or delete a key. */
616 ActionType,
617 KeyName,
619 &ValueName,
620 ValueType,
621 ValueData,
622 ValueDataSize);
623}
624
626NTAPI
629{
631
632 /* Commit the transaction */
634 if (!NT_SUCCESS(Status))
635 {
636 return Status;
637 }
638
639 /* Reset the transaction */
642
643 return Status;
644}
645
647NTAPI
650{
653
654 /* Temporarily safe the current transaction in the 'Log' key value */
656 Status = ZwSetValueKey(Context->KeyHandle,
657 &ValueName,
658 0,
660 Context->Data,
661 Context->Data->CurrentSize);
662 if (!NT_SUCCESS(Status))
663 {
664 return Status;
665 }
666
667 /* Flush the key */
668 Status = NtFlushKey(Context->KeyHandle);
669 if (!NT_SUCCESS(Status))
670 {
671 NtDeleteValueKey(Context->KeyHandle, &ValueName);
672 return Status;
673 }
674
675 /* Now commit the transaction */
677 if (!NT_SUCCESS(Status))
678 {
679 NtDeleteValueKey(Context->KeyHandle, &ValueName);
680 return Status;
681 }
682
683 /* Delete the 'Log' key value */
686
687 /* Reset the transaction */
690
691 return STATUS_SUCCESS;
692}
693
#define ALIGN_UP_BY(size, align)
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:73
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define BufferSize
Definition: mmc.h:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define L(x)
Definition: resources.c:13
#define UlongToPtr(u)
Definition: config.h:106
#define ULONG_PTR
Definition: config.h:101
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
#define ASSERT(a)
Definition: mode.c:44
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
#define REG_BINARY
Definition: nt_native.h:1499
@ KeyValueBasicInformation
Definition: nt_native.h:1183
@ KeyValueFullInformation
Definition: nt_native.h:1184
#define KEY_READ
Definition: nt_native.h:1026
NTSYSAPI NTSTATUS NTAPI NtDeleteValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
Definition: ntapi.c:1014
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1087
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DELETE
Definition: nt_native.h:57
#define KEY_WRITE
Definition: nt_native.h:1034
#define REG_NONE
Definition: nt_native.h:1495
NTSTATUS NTAPI NtFlushKey(IN HANDLE KeyHandle)
Definition: ntapi.c:1085
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_UNKNOWN_REVISION
Definition: ntstatus.h:418
#define STATUS_RXACT_INVALID_STATE
Definition: ntstatus.h:614
#define STATUS_RXACT_STATE_CREATED
Definition: ntstatus.h:193
#define STATUS_RXACT_COMMIT_NECESSARY
Definition: ntstatus.h:284
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSTATUS NTAPI RtlInitializeRXact(HANDLE RootDirectory, BOOLEAN Commit, PRXACT_CONTEXT *OutContext)
Definition: rxact.c:295
NTSTATUS NTAPI RtlAddActionToRXact(PRXACT_CONTEXT Context, ULONG ActionType, PUNICODE_STRING KeyName, ULONG ValueType, PVOID ValueData, ULONG ValueDataSize)
Definition: rxact.c:603
struct _RXACT_INFO * PRXACT_INFO
static VOID NTAPI RXactInitializeContext(PRXACT_CONTEXT Context, HANDLE RootDirectory, HANDLE KeyHandle)
Definition: rxact.c:63
NTSTATUS NTAPI RtlAddAttributeActionToRXact(PRXACT_CONTEXT Context, ULONG ActionType, PUNICODE_STRING KeyName, HANDLE KeyHandle, PUNICODE_STRING ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueDataSize)
Definition: rxact.c:490
struct _RXACT_CONTEXT * PRXACT_CONTEXT
NTSTATUS NTAPI RtlStartRXact(PRXACT_CONTEXT Context)
Definition: rxact.c:246
struct _RXACT_DATA RXACT_DATA
static NTSTATUS NTAPI RXactpCommit(PRXACT_CONTEXT Context)
Definition: rxact.c:125
NTSTATUS NTAPI RtlApplyRXactNoFlush(PRXACT_CONTEXT Context)
Definition: rxact.c:627
#define RXACT_DEFAULT_BUFFER_SIZE
Definition: rxact.c:16
struct _RXACT_DATA * PRXACT_DATA
struct _RXACT_ACTION * PRXACT_ACTION
static NTSTATUS NTAPI RXactpOpenTargetKey(HANDLE RootDirectory, ULONG ActionType, PUNICODE_STRING KeyName, PHANDLE KeyHandle)
Definition: rxact.c:77
struct _RXACT_INFO RXACT_INFO
@ RXactSetValueKey
Definition: rxact.c:55
@ RXactDeleteKey
Definition: rxact.c:54
struct _RXACT_CONTEXT RXACT_CONTEXT
NTSTATUS NTAPI RtlApplyRXact(PRXACT_CONTEXT Context)
Definition: rxact.c:648
struct _RXACT_ACTION RXACT_ACTION
NTSTATUS NTAPI RtlAbortRXact(PRXACT_CONTEXT Context)
Definition: rxact.c:275
NTSTATUS NTAPI RtlpNtQueryValueKey(IN HANDLE KeyHandle, OUT PULONG Type OPTIONAL, OUT PVOID Data OPTIONAL, IN OUT PULONG DataLength OPTIONAL, IN ULONG Unused)
Definition: registry.c:936
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ PVOID Context
Definition: storport.h:2269
Data(int index, int value)
Definition: sort_test.cpp:78
HANDLE KeyHandle
Definition: rxact.c:46
UNICODE_STRING ValueName
Definition: rxact.c:45
ULONG Size
Definition: rxact.c:42
ULONG ValueDataSize
Definition: rxact.c:48
PVOID ValueData
Definition: rxact.c:49
ULONG Type
Definition: rxact.c:43
UNICODE_STRING KeyName
Definition: rxact.c:44
ULONG ValueType
Definition: rxact.c:47
HANDLE KeyHandle
Definition: rxact.c:35
BOOLEAN CanUseHandles
Definition: rxact.c:36
PRXACT_DATA Data
Definition: rxact.c:37
HANDLE RootDirectory
Definition: rxact.c:34
ULONG BufferSize
Definition: rxact.c:28
ULONG ActionCount
Definition: rxact.c:27
ULONG CurrentSize
Definition: rxact.c:29
ULONG Revision
Definition: rxact.c:20
ULONG Unknown1
Definition: rxact.c:21
ULONG Unknown2
Definition: rxact.c:22
uint16_t * PWSTR
Definition: typedefs.h:56
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4445
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243