Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

rxact.c File Reference

#include "ntrtlp.h"

Go to the source code of this file.

Classes

struct  _RTLP_RXACT
struct  _RXACT_LOG_ENTRY

Defines

#define INVALID_HANDLE_VALUE   (HANDLE)-1
#define RTLP_RXACT_REVISION1   (1l)
#define RTLP_RXACT_CURRENT_REVISION   RTLP_RXACT_REVISION1
#define RTLP_RXACT_KEY_NAME   L"RXACT"
#define RTLP_RXACT_LOG_NAME   L"Log"
#define RTLP_INITIAL_LOG_SIZE   0x4000
#define DwordAlign(Value)

Typedefs

typedef enum _RTLP_RXACT_STATE RTLP_RXACT_STATE
typedef enum _RTLP_RXACT_STATEPRTLP_RXACT_STATE
typedef _RTLP_RXACT RTLP_RXACT
typedef _RTLP_RXACTPRTLP_RXACT
typedef _RXACT_LOG_ENTRY RXACT_LOG_ENTRY
typedef _RXACT_LOG_ENTRYPRXACT_LOG_ENTRY

Enumerations

enum  _RTLP_RXACT_STATE { RtlpRXactStateNoTransaction = 2, RtlpRXactStateCommitting }

Functions

NTSTATUS RXactpCommit (IN PRTL_RXACT_CONTEXT RXactContext)
NTSTATUS RXactpOpenTargetKey (IN HANDLE RootRegistryKey, IN RTL_RXACT_OPERATION Operation, IN PUNICODE_STRING SubKeyName, OUT PHANDLE TargetKey)
VOID RXactInitializeContext (IN PRTL_RXACT_CONTEXT RXactContext, IN HANDLE RootRegistryKey, IN HANDLE RXactKey)
NTSTATUS RtlInitializeRXact (IN HANDLE RootRegistryKey, IN BOOLEAN CommitIfNecessary, OUT PRTL_RXACT_CONTEXT *RXactContext)
NTSTATUS RtlStartRXact (IN PRTL_RXACT_CONTEXT RXactContext)
NTSTATUS RtlAbortRXact (IN PRTL_RXACT_CONTEXT RXactContext)
NTSTATUS RtlAddAttributeActionToRXact (IN PRTL_RXACT_CONTEXT RXactContext, IN RTL_RXACT_OPERATION Operation, IN PUNICODE_STRING SubKeyName, IN HANDLE KeyHandle OPTIONAL, IN PUNICODE_STRING AttributeName, IN ULONG NewValueType, IN PVOID NewValue, IN ULONG NewValueLength)
NTSTATUS RtlAddActionToRXact (IN PRTL_RXACT_CONTEXT RXactContext, IN RTL_RXACT_OPERATION Operation, IN PUNICODE_STRING SubKeyName, IN ULONG NewKeyValueType, IN PVOID NewKeyValue OPTIONAL, IN ULONG NewKeyValueLength)
NTSTATUS RtlApplyRXact (IN PRTL_RXACT_CONTEXT RXactContext)
NTSTATUS RtlApplyRXactNoFlush (IN PRTL_RXACT_CONTEXT RXactContext)


Define Documentation

#define DwordAlign Value   ) 
 

Value:

( \ (ULONG)((((ULONG)(Value)) + 3) & 0xfffffffc) \ )

Definition at line 242 of file rxact.c.

Referenced by RtlAddAttributeActionToRXact().

#define INVALID_HANDLE_VALUE   (HANDLE)-1
 

Definition at line 212 of file rxact.c.

Referenced by CreateConsoleScreenBuffer(), DllMain(), DoDump(), DuplicateConsoleHandle(), ExtractIconFromEXE(), FindActiveScreenBufferHandle(), InstallProfiles(), InternalOpenColorProfile(), LoadLink(), OpenConsoleW(), OpenConsoleWInternal(), OpenMonitor(), PrivateExtractIconsW(), ReadChars(), RtlAddActionToRXact(), RtlLoadObjectFromDIBFile(), RXactpCommit(), ScanHive(), xxxLbDir(), and xxxLbInsertFile().

#define RTLP_INITIAL_LOG_SIZE   0x4000
 

Definition at line 236 of file rxact.c.

Referenced by RtlStartRXact().

#define RTLP_RXACT_CURRENT_REVISION   RTLP_RXACT_REVISION1
 

Definition at line 229 of file rxact.c.

#define RTLP_RXACT_KEY_NAME   L"RXACT"
 

Definition at line 232 of file rxact.c.

Referenced by RtlInitializeRXact().

#define RTLP_RXACT_LOG_NAME   L"Log"
 

Definition at line 234 of file rxact.c.

Referenced by RtlApplyRXact(), and RtlInitializeRXact().

#define RTLP_RXACT_REVISION1   (1l)
 

Definition at line 228 of file rxact.c.

Referenced by RtlInitializeRXact().


Typedef Documentation

typedef struct _RTLP_RXACT * PRTLP_RXACT
 

typedef enum _RTLP_RXACT_STATE * PRTLP_RXACT_STATE
 

typedef struct _RXACT_LOG_ENTRY * PRXACT_LOG_ENTRY
 

Referenced by RtlAddAttributeActionToRXact(), and RXactpCommit().

typedef struct _RTLP_RXACT RTLP_RXACT
 

typedef enum _RTLP_RXACT_STATE RTLP_RXACT_STATE
 

typedef struct _RXACT_LOG_ENTRY RXACT_LOG_ENTRY
 


Enumeration Type Documentation

enum _RTLP_RXACT_STATE
 

Enumeration values:
RtlpRXactStateNoTransaction 
RtlpRXactStateCommitting 

Definition at line 260 of file rxact.c.


Function Documentation

NTSTATUS RtlAbortRXact IN PRTL_RXACT_CONTEXT  RXactContext  ) 
 

Definition at line 833 of file rxact.c.

References NULL, RTL_PAGED_CODE, RtlFreeHeap, RXactInitializeContext(), and VOID().

Referenced by RtlApplyRXact(), RtlApplyRXactNoFlush(), and RtlInitializeRXact().

00839 : 00840 00841 This routine is used to abort a transaction in a registry sub-tree. 00842 00843 Arguments: 00844 00845 RootRegistryKey - A handle to the registry key within whose sub-tree 00846 the transaction is to be aborted. 00847 00848 Return Value: 00849 00850 STATUS_SUCCESS - Indicates the transaction was aborted. 00851 00852 00853 STATUS_UNKNOWN_REVISION - Indicates that a transaction state 00854 exists for the specified sub-tree, but has a revision level that is 00855 unknown by this service. 00856 00857 00858 STATUS_RXACT_INVALID_STATE - Indicates that the transaction state 00859 of the registry sub-tree is incompatible with the requested operation. 00860 For example, a request to start a new transaction while one is already 00861 in progress, or a request to apply a transaction when one is not 00862 currently in progress. This may also indicate that there is no 00863 transaction state at all for the specified registry sub-tree. 00864 00865 --*/ 00866 00867 { 00868 RTL_PAGED_CODE(); 00869 00870 if ( RXactContext->RXactLog == NULL ) { 00871 00872 // 00873 // There is no transaction in progress for this 00874 // context. Return an error. 00875 // 00876 00877 return( STATUS_RXACT_INVALID_STATE ); 00878 } 00879 00880 (VOID) RtlFreeHeap( RtlProcessHeap(), 0, RXactContext->RXactLog ); 00881 00882 // 00883 // Reinitialize the RXactContext structure with the same initial data. 00884 // 00885 00886 RXactInitializeContext( 00887 RXactContext, 00888 RXactContext->RootRegistryKey, 00889 RXactContext->RXactKey 00890 ); 00891 00892 00893 return( STATUS_SUCCESS ); 00894 00895 }

NTSTATUS RtlAddActionToRXact IN PRTL_RXACT_CONTEXT  RXactContext,
IN RTL_RXACT_OPERATION  Operation,
IN PUNICODE_STRING  SubKeyName,
IN ULONG  NewKeyValueType,
IN PVOID NewKeyValue  OPTIONAL,
IN ULONG  NewKeyValueLength
 

Definition at line 1156 of file rxact.c.

References INVALID_HANDLE_VALUE, NTSTATUS(), NULL, RTL_PAGED_CODE, RtlAddAttributeActionToRXact(), RtlInitUnicodeString(), and Status.

01167 : 01168 01169 This routine is used to add a new action to the transaction operation log. 01170 Upon commit, these operations are applied in the order they are added 01171 to the log. 01172 01173 Arguments: 01174 01175 RXactContext - Supplies a pointer to the RXactContext structure for this 01176 subsystem's root registry key. 01177 01178 Operation - Indicates the type of operation to perform (e.g., delete 01179 a sub-key or set the value of a sub-key). Sub-keys may be created 01180 by setting a value of a previously non-existent sub-key. This will 01181 cause all sub-keys between the root and the specified sub-key to 01182 be created. 01183 01184 SubKeyName - Specifies the name of the target registry key. This name 01185 is relative to the Root of the Registry transaction sub-tree 01186 and must NOT start with a delimiter character ("\"). 01187 01188 NewKeyValueType - (Optional) Contains the KeyValueType to assign 01189 to the target registry key. This parameter is ignored if the 01190 Operation is not RtlRXactOperationSetValue. 01191 01192 NewKeyValue - (Optional) Points to a buffer containing the value 01193 to assign to the specified target registry key. This parameter 01194 is ignored if the Operation is not RtlRXactOperationSetValue. 01195 01196 NewKeyValueLength - Indicates the length (number of bytes) of the 01197 NewKeyValue buffer. This parameter is ignored if the Operation 01198 is not RtlRXactOperationSetValue. 01199 01200 Return Value: 01201 01202 STATUS_SUCCESS - Indicates the request completed successfully.. 01203 01204 01205 STATUS_UNKNOWN_REVISION - Indicates that a transaction state 01206 exists for the specified sub-tree, but has a revision level that is 01207 unknown by this service. 01208 01209 Others - Other status values that may be returned from registry key 01210 services (such as STATUS_ACCESS_DENIED). 01211 01212 --*/ 01213 { 01214 UNICODE_STRING AttributeName; 01215 NTSTATUS Status; 01216 01217 RTL_PAGED_CODE(); 01218 01219 RtlInitUnicodeString( &AttributeName, NULL ); 01220 01221 Status = RtlAddAttributeActionToRXact( 01222 RXactContext, 01223 Operation, 01224 SubKeyName, 01225 INVALID_HANDLE_VALUE, 01226 &AttributeName, 01227 NewKeyValueType, 01228 NewKeyValue, 01229 NewKeyValueLength 01230 ); 01231 01232 return( Status ); 01233 01234 01235 }

NTSTATUS RtlAddAttributeActionToRXact IN PRTL_RXACT_CONTEXT  RXactContext,
IN RTL_RXACT_OPERATION  Operation,
IN PUNICODE_STRING  SubKeyName,
IN HANDLE KeyHandle  OPTIONAL,
IN PUNICODE_STRING  AttributeName,
IN ULONG  NewValueType,
IN PVOID  NewValue,
IN ULONG  NewValueLength
 

Definition at line 900 of file rxact.c.

References ALIGN_UP, _RXACT_LOG_ENTRY::AttributeName, DwordAlign, End, _RXACT_LOG_ENTRY::KeyHandle, _RXACT_LOG_ENTRY::LogEntrySize, _RXACT_LOG_ENTRY::NewKeyValue, _RXACT_LOG_ENTRY::NewKeyValueLength, _RXACT_LOG_ENTRY::NewKeyValueType, NULL, _RXACT_LOG_ENTRY::Operation, PRXACT_LOG_ENTRY, RTL_PAGED_CODE, RtlAllocateHeap, RtlFreeHeap, and _RXACT_LOG_ENTRY::SubKeyName.

Referenced by RtlAddActionToRXact().

00913 : 00914 00915 This routine is used to add a new action to the transaction operation log. 00916 Upon commit, these operations are applied in the order they are added 00917 to the log. 00918 00919 This routine differs from RtlAddActionToRXact in that it takes an Attribute 00920 Name parameter, rather than using the default ("NULL") Attribute of the 00921 specified key. 00922 00923 00924 Arguments: 00925 00926 RXactContext - Supplies a pointer to the RXactContext structure for this 00927 subsystem's root registry key. 00928 00929 Operation - Indicates the type of operation to perform (e.g., delete 00930 a sub-key or set the value of a sub-key). Sub-keys may be created 00931 by setting a value of a previously non-existent sub-key. This will 00932 cause all sub-keys between the root and the specified sub-key to 00933 be created. 00934 00935 SubKeyName - Specifies the name of the target registry key. This name 00936 is relative to the Root of the Registry transaction sub-tree 00937 and must NOT start with a delimiter character ("\"). 00938 00939 KeyHandle - Optionally supplies a handle to the target key. If 00940 not specified, the name passed for SubKeyName will determine 00941 the target key. 00942 00943 AttributeName - Supplies the name of the key attribute to be 00944 modified. 00945 00946 NewKeyValueType - (Optional) Contains the KeyValueType to assign 00947 to the target registry key. This parameter is ignored if the 00948 Operation is not RtlRXactOperationSetValue. 00949 00950 NewKeyValue - (Optional) Points to a buffer containing the value 00951 to assign to the specified target registry key. This parameter 00952 is ignored if the Operation is not RtlRXactOperationSetValue. 00953 00954 NewKeyValueLength - Indicates the length (number of bytes) of the 00955 NewKeyValue buffer. This parameter is ignored if the Operation 00956 is not RtlRXactOperationSetValue. 00957 00958 00959 Return Value: 00960 00961 STATUS_SUCCESS - Indicates the request completed successfully.. 00962 00963 STATUS_INVALID_PARAMETER - Indicates that an unknown Operation 00964 was requested. 00965 00966 STATUS_NO_MEMORY - Insufficient memeory was available to complete 00967 this operation. 00968 00969 STATUS_UNKNOWN_REVISION - Indicates that a transaction state 00970 exists for the specified sub-tree, but has a revision level that is 00971 unknown by this service. 00972 00973 00974 --*/ 00975 00976 { 00977 00978 PRTL_RXACT_LOG NewLog; 00979 PRXACT_LOG_ENTRY Base; 00980 00981 ULONG End; 00982 ULONG LogEntrySize; 00983 ULONG NewLogSize; 00984 00985 RTL_PAGED_CODE(); 00986 00987 // 00988 // Make sure we were passed a legitimate operation. 00989 // 00990 00991 if ( (Operation != RtlRXactOperationDelete) && 00992 (Operation != RtlRXactOperationSetValue) ) { 00993 return STATUS_INVALID_PARAMETER; 00994 } 00995 00996 // 00997 // Compute the total size of the new data 00998 // 00999 01000 LogEntrySize = sizeof( RXACT_LOG_ENTRY ) + 01001 DwordAlign( SubKeyName->Length ) + 01002 DwordAlign( AttributeName->Length ) + 01003 DwordAlign( NewValueLength ); 01004 01005 LogEntrySize = ALIGN_UP( LogEntrySize, PVOID ); 01006 01007 // 01008 // Make sure there is enough space in the current 01009 // log file for this data. If not, we must create 01010 // a larger log, copy all the old data, and then 01011 // append this to the end. 01012 // 01013 01014 if ( RXactContext->RXactLog->LogSizeInUse + LogEntrySize > 01015 RXactContext->RXactLog->LogSize ) { 01016 01017 // 01018 // We must allocate a bigger log file. 01019 // 01020 01021 NewLogSize = RXactContext->RXactLog->LogSize; 01022 01023 do { 01024 01025 NewLogSize = NewLogSize * 2; 01026 01027 } while ( NewLogSize < 01028 ( RXactContext->RXactLog->LogSizeInUse + LogEntrySize ) ); 01029 01030 NewLog = RtlAllocateHeap( RtlProcessHeap(), 0, NewLogSize ); 01031 01032 if ( NewLog == NULL ) { 01033 return( STATUS_NO_MEMORY ); 01034 } 01035 01036 // 01037 // Copy over previous information 01038 // 01039 01040 RtlMoveMemory( NewLog, RXactContext->RXactLog, RXactContext->RXactLog->LogSizeInUse ); 01041 01042 // 01043 // Free the old log file 01044 // 01045 01046 RtlFreeHeap( RtlProcessHeap(), 0, RXactContext->RXactLog ); 01047 01048 // 01049 // Install the new log file and adjust its size in its header 01050 // 01051 01052 RXactContext->RXactLog = NewLog; 01053 RXactContext->RXactLog->LogSize = NewLogSize; 01054 } 01055 01056 // 01057 // The log file is big enough, append data to 01058 // the end. 01059 // 01060 01061 Base = (PRXACT_LOG_ENTRY)((PCHAR)(RXactContext->RXactLog) + 01062 (RXactContext->RXactLog->LogSizeInUse)); 01063 01064 01065 // 01066 // Append each parameter to the end of the log. Unicode string data 01067 // will be appended to the end of the entry. The Buffer field in the 01068 // Unicode string structure will contain the offset to the Buffer, 01069 // relative to the beginning of the log file. 01070 // 01071 01072 Base->LogEntrySize = LogEntrySize; 01073 Base->Operation = Operation; 01074 Base->SubKeyName = *SubKeyName; 01075 Base->AttributeName = *AttributeName; 01076 Base->NewKeyValueType = NewValueType; 01077 Base->NewKeyValueLength = NewValueLength; 01078 Base->KeyHandle = KeyHandle; 01079 01080 // 01081 // Fill in the variable length data: SubKeyName, AttributeName, 01082 // and NewKeyValue 01083 // 01084 01085 // 01086 // End is an offset relative to the beginning of the entire log 01087 // structure. It is initialized to 'point' to the offset immediately 01088 // following the structure we just filled in above. 01089 // 01090 01091 End = (ULONG)((RXactContext->RXactLog->LogSizeInUse) + 01092 sizeof( *Base )); 01093 01094 01095 // 01096 // Append SubKeyName information to the log file 01097 // 01098 01099 RtlMoveMemory ( 01100 (PCHAR)(RXactContext->RXactLog) + End, 01101 SubKeyName->Buffer, 01102 SubKeyName->Length 01103 ); 01104 01105 Base->SubKeyName.Buffer = (PWSTR)ULongToPtr(End); 01106 End += DwordAlign( SubKeyName->Length ); 01107 01108 01109 01110 // 01111 // Append AttributeName information to the log file 01112 // 01113 01114 01115 RtlMoveMemory( 01116 (PCHAR)(RXactContext->RXactLog) + End, 01117 AttributeName->Buffer, 01118 AttributeName->Length 01119 ); 01120 01121 Base->AttributeName.Buffer = (PWSTR)ULongToPtr(End); 01122 End += DwordAlign( AttributeName->Length ); 01123 01124 01125 01126 // 01127 // Append NewKeyValue information (if present) to the log file 01128 // 01129 01130 if ( Operation == RtlRXactOperationSetValue ) { 01131 01132 RtlMoveMemory( 01133 (PCHAR)(RXactContext->RXactLog) + End, 01134 NewValue, 01135 NewValueLength 01136 ); 01137 01138 Base->NewKeyValue = (PVOID)ULongToPtr(End); 01139 End += DwordAlign( NewValueLength ); 01140 } 01141 01142 End = ALIGN_UP( End, PVOID ); 01143 01144 RXactContext->RXactLog->LogSizeInUse = End; 01145 RXactContext->RXactLog->OperationCount++; 01146 01147 // 01148 // We're done 01149 // 01150 01151 return(STATUS_SUCCESS); 01152 }

NTSTATUS RtlApplyRXact IN PRTL_RXACT_CONTEXT  RXactContext  ) 
 

Definition at line 1240 of file rxact.c.

References ASSERT, NT_SUCCESS, NtDeleteValueKey(), NtFlushKey(), NtSetValueKey(), NTSTATUS(), RTL_PAGED_CODE, RtlAbortRXact(), RtlInitUnicodeString(), RTLP_RXACT_LOG_NAME, RXactpCommit(), Status, and VOID().

01246 : 01247 01248 This routine is used to apply the changes of a registry sub-tree 01249 Transaction to that registry sub-tree. This routine is meant to be 01250 called for the common case, where the hive is automatically 01251 lazy-flushed. That means that this routine must write the change log 01252 to disk, then flush the hive (to ensure that pieces of changes aren't 01253 lazy-written to disk before this routine finishes an atomic operation), 01254 the apply the changes, then delete the change log. 01255 01256 The actual changes will be lazy-written to disk, but the registry 01257 guarantees that none or all will make it. If the machine goes down 01258 while this routine is executing, the flushed change log guarantees 01259 that the hive can be put into a consistent state. 01260 01261 Arguments: 01262 01263 RXactContext - Supplies a pointer to the RXactContext structure for this 01264 subsystem's root registry key. 01265 01266 Return Value: 01267 01268 STATUS_SUCCESS - Indicates the transaction was completed. 01269 01270 STATUS_UNKNOWN_REVISION - Indicates that a transaction state 01271 exists for the specified sub-tree, but has a revision level that is 01272 unknown by this service. 01273 01274 01275 STATUS_RXACT_INVALID_STATE - Indicates that the transaction state 01276 of the registry sub-tree is incompatible with the requested operation. 01277 For example, a request to start a new transaction while one is already 01278 in progress, or a request to apply a transaction when one is not 01279 currently in progress. This may also indicate that there is no 01280 transaction state at all for the specified registry sub-tree. 01281 01282 01283 --*/ 01284 { 01285 NTSTATUS Status; 01286 UNICODE_STRING LogName; 01287 HANDLE RXactKey; 01288 01289 RTL_PAGED_CODE(); 01290 01291 // 01292 // Commit the contents of the current log to disk 01293 // 01294 01295 RXactKey = RXactContext->RXactKey; 01296 01297 RtlInitUnicodeString( &LogName, RTLP_RXACT_LOG_NAME ); 01298 01299 Status = NtSetValueKey( RXactKey, 01300 &LogName, // ValueName 01301 0, // TitleIndex 01302 REG_BINARY, 01303 RXactContext->RXactLog, 01304 RXactContext->RXactLog->LogSizeInUse 01305 ); 01306 01307 if ( !NT_SUCCESS( Status )) { 01308 return( Status ); 01309 } 01310 01311 Status = NtFlushKey( RXactKey ); 01312 01313 if ( !NT_SUCCESS( Status )) { 01314 01315 // 01316 // If this fails, maintain the in-memory data, 01317 // but get rid of what we just tried to write 01318 // to disk. 01319 // 01320 // Ignore the error, since we're in a funky 01321 // state right now. 01322 // 01323 01324 (VOID) NtDeleteValueKey( RXactKey, &LogName ); 01325 01326 return( Status ); 01327 } 01328 01329 // 01330 // The log is safe, now execute what is in it 01331 // 01332 01333 Status = RXactpCommit( RXactContext ); 01334 01335 if ( !NT_SUCCESS( Status )) { 01336 01337 // 01338 // As above, try to get rid of what's on 01339 // disk, leave the in-memory stuff alone, 01340 // so that the caller may try again. 01341 // 01342 01343 (VOID) NtDeleteValueKey( RXactKey, &LogName ); 01344 01345 return( Status ); 01346 } 01347 01348 // 01349 // Delete the log file value and data 01350 // 01351 01352 Status = NtDeleteValueKey( RXactKey, &LogName ); 01353 01354 // 01355 // This should never fail 01356 // 01357 01358 ASSERT( NT_SUCCESS( Status )); 01359 01360 // 01361 // Get rid of the in memory data structures. Abort 01362 // does exactly what we want to do. 01363 // 01364 01365 Status = RtlAbortRXact( RXactContext ); 01366 01367 // 01368 // This should never fail 01369 // 01370 01371 ASSERT( NT_SUCCESS( Status )); 01372 01373 return( STATUS_SUCCESS ); 01374 01375 }

NTSTATUS RtlApplyRXactNoFlush IN PRTL_RXACT_CONTEXT  RXactContext  ) 
 

Definition at line 1380 of file rxact.c.

References ASSERT, NT_SUCCESS, NTSTATUS(), RTL_PAGED_CODE, RtlAbortRXact(), RXactpCommit(), and Status.

01386 : 01387 01388 This routine is used to apply the changes of a registry sub-tree 01389 Transaction to that registry sub-tree. This routine should only be 01390 called for special hives that do not have automatic lazy-flushing. 01391 The caller must decide when to flush the hive in order to guarantee 01392 a consistent hive. 01393 01394 Arguments: 01395 01396 RXactContext - Supplies a pointer to the RXactContext structure for this 01397 subsystem's root registry key. 01398 01399 Return Value: 01400 01401 STATUS_SUCCESS - Indicates the transaction was completed. 01402 01403 STATUS_UNKNOWN_REVISION - Indicates that a transaction state 01404 exists for the specified sub-tree, but has a revision level that is 01405 unknown by this service. 01406 01407 01408 STATUS_RXACT_INVALID_STATE - Indicates that the transaction state 01409 of the registry sub-tree is incompatible with the requested operation. 01410 For example, a request to start a new transaction while one is already 01411 in progress, or a request to apply a transaction when one is not 01412 currently in progress. This may also indicate that there is no 01413 transaction state at all for the specified registry sub-tree. 01414 01415 01416 --*/ 01417 { 01418 NTSTATUS Status; 01419 01420 RTL_PAGED_CODE(); 01421 01422 // 01423 // Execute the contents of the RXACT log. 01424 // 01425 01426 Status = RXactpCommit( RXactContext ); 01427 01428 if ( NT_SUCCESS( Status ) ) { 01429 01430 // 01431 // Get rid of the in memory data structures. Abort 01432 // does exactly what we want to do. 01433 // 01434 01435 Status = RtlAbortRXact( RXactContext ); 01436 01437 // 01438 // This should never fail 01439 // 01440 01441 ASSERT( NT_SUCCESS( Status )); 01442 } 01443 01444 return( Status ); 01445 01446 }

NTSTATUS RtlInitializeRXact IN HANDLE  RootRegistryKey,
IN BOOLEAN  CommitIfNecessary,
OUT PRTL_RXACT_CONTEXT *  RXactContext
 

Definition at line 341 of file rxact.c.

References ASSERT, FALSE, NT_SUCCESS, NtClose(), NtCreateKey(), NtDeleteKey(), NtDeleteValueKey(), NtQueryValueKey(), NtSetValueKey(), NTSTATUS(), NULL, _RTLP_RXACT::Revision, RTL_PAGED_CODE, RtlAbortRXact(), RtlAllocateHeap, RtlFreeHeap, RtlInitUnicodeString(), RTLP_RXACT_KEY_NAME, RTLP_RXACT_LOG_NAME, RTLP_RXACT_REVISION1, RtlpNtQueryValueKey(), RXactInitializeContext(), RXactpCommit(), Status, and ValueName.

00349 : 00350 00351 This routine should be called by a server exactly once when it starts. 00352 This routine will check to see that the registry transaction information 00353 exists for the specified registry sub-tree, and will create it if it 00354 doesn't exist. 00355 00356 Arguments: 00357 00358 RootRegistryKey - A handle to the registry key within whose sub-tree 00359 a transaction is to be initialized. 00360 00361 CommitIfNecessary - A BOOLEAN value indicating whether or not any 00362 previously aborted commit discovered should be commited at this 00363 time. A value of TRUE indicates the commit should be applied 00364 if encountered. A value of FALSE indicates a previously 00365 aborted COMMIT should not be committed at this time. 00366 00367 RXactContext - Returns a pointer to an RTL_RXACT_CONTEXT structure 00368 allocated out of the local heap. The caller must keep this 00369 pointer and pass it back in for all future RXact transactions 00370 for the passed RootRegistryKey. 00371 00372 00373 Return Value: 00374 00375 STATUS_SUCCESS - Indicates the transaction state already exists for the 00376 registry sub-tree and is already in the NO_TRANSACTION state. 00377 00378 STATUS_UNKNOWN_REVISION - Indicates that a transaction state already 00379 exists for the specified sub-tree, but is a revision level that is 00380 unknown by this service. 00381 00382 STATUS_RXACT_STATE_CREATED - This informational level status indicates 00383 that a specified registry sub-tree transaction state did not yet 00384 exist and had to be created. 00385 00386 STATUS_RXACT_COMMIT_NECESSARY - This warning level status indicates that the 00387 transaction state already exists for the registry sub-tree, but that 00388 a transaction commit was previously aborted. The commit has NOT been 00389 completed. Another call to this service with a CommitIfNecessary value 00390 of TRUE may be used to commit the transaction. 00391 00392 00393 STATUS_RXACT_INVALID_STATE - Indicates that the transaction state 00394 of the registry sub-tree is incompatible with the requested operation. 00395 For example, a request to start a new transaction while one is already 00396 in progress, or a request to apply a transaction when one is not 00397 currently in progress. 00398 00399 --*/ 00400 00401 { 00402 00403 HANDLE RXactKey; 00404 LARGE_INTEGER LastWriteTime; 00405 NTSTATUS Status, TmpStatus; 00406 OBJECT_ATTRIBUTES RXactAttributes; 00407 PKEY_VALUE_FULL_INFORMATION FullInformation; 00408 RTLP_RXACT RXactKeyValue; 00409 UCHAR BasicInformation[128]; // Should be more than long enough 00410 ULONG Disposition; 00411 ULONG KeyValueLength; 00412 ULONG KeyValueType; 00413 ULONG ResultLength; 00414 UNICODE_STRING RXactKeyName; 00415 UNICODE_STRING ValueName; 00416 UNICODE_STRING NullName; 00417 00418 RTL_PAGED_CODE(); 00419 00420 // 00421 // Initialize some stuff 00422 // 00423 00424 KeyValueLength = (ULONG)sizeof( RTLP_RXACT ); 00425 KeyValueType = 0; // Not used by RXact 00426 00427 RtlInitUnicodeString( &NullName, NULL ); 00428 00429 // 00430 // Create or open the RXACT key. 00431 // 00432 00433 RtlInitUnicodeString( &RXactKeyName, RTLP_RXACT_KEY_NAME); 00434 00435 InitializeObjectAttributes( 00436 &RXactAttributes, 00437 &RXactKeyName, 00438 OBJ_CASE_INSENSITIVE | OBJ_OPENIF, 00439 RootRegistryKey, 00440 NULL); 00441 00442 // Status = RtlpNtCreateKey( 00443 // &RXactKey, 00444 // (KEY_READ | KEY_WRITE | DELETE), 00445 // &RXactAttributes, 00446 // 0, 00447 // NULL, 00448 // &Disposition 00449 // ); 00450 00451 Status = NtCreateKey( &RXactKey, 00452 (KEY_READ | KEY_WRITE | DELETE), 00453 &RXactAttributes, 00454 0, //TitleIndex 00455 NULL, //Class OPTIONAL, 00456 REG_OPTION_NON_VOLATILE, //CreateOptions, 00457 &Disposition 00458 ); 00459 00460 if ( !NT_SUCCESS(Status) ) { 00461 return(Status); 00462 } 00463 00464 // 00465 // Allocate the RXactContext block 00466 // 00467 00468 *RXactContext = RtlAllocateHeap( RtlProcessHeap(), 0, sizeof( RTL_RXACT_CONTEXT )); 00469 00470 if ( *RXactContext == NULL ) { 00471 00472 // 00473 // Something prevented value assignment... 00474 // Get rid of the RXact key and return the error 00475 // 00476 00477 TmpStatus = NtDeleteKey( RXactKey ); 00478 ASSERT(NT_SUCCESS(TmpStatus)); //Safe to ignore, notify security group 00479 TmpStatus = NtClose( RXactKey ); 00480 ASSERT(NT_SUCCESS(TmpStatus)); //Safe to ignore, notify security group 00481 00482 return( STATUS_NO_MEMORY ); 00483 } 00484 00485 // 00486 // Initialize the newly created RXactContext structure. 00487 // 00488 00489 RXactInitializeContext( *RXactContext, RootRegistryKey, RXactKey ); 00490 00491 // 00492 // If we created (as opposed to opened an existing) rxact key, 00493 // then we need to initialize it. 00494 // 00495 00496 if ( Disposition == REG_CREATED_NEW_KEY ) { 00497 00498 RXactKeyValue.Revision = RTLP_RXACT_REVISION1; 00499 00500 Status = NtSetValueKey( RXactKey, 00501 &NullName, // ValueName 00502 0, // TitleIndex 00503 KeyValueType, 00504 &RXactKeyValue, 00505 KeyValueLength 00506 ); 00507 00508 if ( !NT_SUCCESS(Status) ) { 00509 00510 // 00511 // Something prevented value assignment... 00512 // Get rid of the RXact key and return the error 00513 // 00514 00515 TmpStatus = NtDeleteKey( RXactKey ); 00516 ASSERT(NT_SUCCESS(TmpStatus)); //Safe to ignore, notify security group 00517 TmpStatus = NtClose( RXactKey ); 00518 ASSERT(NT_SUCCESS(TmpStatus)); //Safe to ignore, notify security group 00519 00520 RtlFreeHeap( RtlProcessHeap(), 0, *RXactContext ); 00521 00522 return( Status ); 00523 } 00524 00525 return( STATUS_RXACT_STATE_CREATED ); 00526 } 00527 00528 00529 00530 // 00531 // We have opened an existing RXACT key. 00532 // See if it is a revision level we know about. 00533 // 00534 00535 Status = RtlpNtQueryValueKey( 00536 RXactKey, // KeyHandle 00537 &KeyValueType, // KeyValueType 00538 &RXactKeyValue, // KeyValue 00539 &KeyValueLength, // KeyValueLength 00540 &LastWriteTime // LastWriteTime 00541 ); 00542 00543 00544 if ( !NT_SUCCESS(Status) ) { 00545 00546 // 00547 // Something prevented value query... 00548 // 00549 00550 TmpStatus = NtClose( RXactKey ); 00551 ASSERT(NT_SUCCESS(TmpStatus)); //Safe to ignore, notify security group 00552 RtlFreeHeap( RtlProcessHeap(), 0, *RXactContext ); 00553 return( Status ); 00554 } 00555 00556 00557 if ( KeyValueLength != (ULONG)sizeof(RTLP_RXACT) ) { 00558 TmpStatus = NtClose( RXactKey ); 00559 ASSERT(NT_SUCCESS(TmpStatus)); //Safe to ignore, notify security group 00560 RtlFreeHeap( RtlProcessHeap(), 0, *RXactContext ); 00561 return( STATUS_UNKNOWN_REVISION ); 00562 } 00563 00564 if (RXactKeyValue.Revision != RTLP_RXACT_REVISION1) { 00565 TmpStatus = NtClose( RXactKey ); 00566 ASSERT(NT_SUCCESS(TmpStatus)); //Safe to ignore, notify security group 00567 RtlFreeHeap( RtlProcessHeap(), 0, *RXactContext ); 00568 return( STATUS_UNKNOWN_REVISION ); 00569 } 00570 00571 00572 00573 // 00574 // Right revision... 00575 // See if there is a transaction or commit in progress. If not, 00576 // return success 00577 // 00578 00579 // 00580 // If a log file exists, then we are committing. 00581 // 00582 00583 RtlInitUnicodeString( &ValueName, RTLP_RXACT_LOG_NAME ); 00584 00585 Status = NtQueryValueKey( 00586 RXactKey, 00587 &ValueName, 00588 KeyValueBasicInformation, 00589 &BasicInformation, 00590 128, 00591 &ResultLength 00592 ); 00593 00594 if ( NT_SUCCESS( Status )) { 00595 00596 // 00597 // We found a value called 'Log'. This means that a commit 00598 // was in progress. 00599 // 00600 00601 if ( CommitIfNecessary ) { 00602 00603 // 00604 // Query the full value of the log, then call a low level routine 00605 // to actually perform the commit. 00606 // 00607 00608 Status = NtQueryValueKey( 00609 RXactKey, 00610 &ValueName, 00611 KeyValueFullInformation, 00612 NULL, 00613 0, 00614 &ResultLength 00615 ); 00616 00617 if ( Status != STATUS_BUFFER_TOO_SMALL ) { 00618 return( Status ); 00619 } 00620 00621 FullInformation = RtlAllocateHeap( RtlProcessHeap(), 0, ResultLength ); 00622 00623 if ( FullInformation == NULL ) { 00624 return( STATUS_NO_MEMORY ); 00625 } 00626 00627 00628 Status = NtQueryValueKey( 00629 RXactKey, 00630 &ValueName, 00631 KeyValueFullInformation, 00632 FullInformation, 00633 ResultLength, 00634 &ResultLength 00635 ); 00636 00637 if ( !NT_SUCCESS( Status )) { 00638 00639 RtlFreeHeap( RtlProcessHeap(), 0, FullInformation ); 00640 RtlFreeHeap( RtlProcessHeap(), 0, *RXactContext ); 00641 return( Status ); 00642 } 00643 00644 // 00645 // The log information is buried in the returned FullInformation 00646 // buffer. Dig it out and make the RXactLog in the RXactContext 00647 // structure point to it. Then commit. 00648 // 00649 00650 (*RXactContext)->RXactLog = (PRTL_RXACT_LOG)((PCHAR)FullInformation + FullInformation->DataOffset); 00651 00652 // 00653 // Don't use any handles we may find in the log file 00654 // 00655 00656 (*RXactContext)->HandlesValid = FALSE; 00657 00658 Status = RXactpCommit( *RXactContext ); 00659 00660 if ( !NT_SUCCESS( Status )) { 00661 00662 RtlFreeHeap( RtlProcessHeap(), 0, FullInformation ); 00663 RtlFreeHeap( RtlProcessHeap(), 0, *RXactContext ); 00664 return( Status ); 00665 } 00666 00667 00668 // 00669 // The commit was successful. Clean up. 00670 // Delete the log file value and data 00671 // 00672 00673 Status = NtDeleteValueKey( RXactKey, &ValueName ); 00674 00675 // 00676 // This should never fail 00677 // 00678 00679 ASSERT( NT_SUCCESS( Status )); 00680 00681 // 00682 // Get rid of the in memory data structures. Abort 00683 // will free the RXactLog, so put what we want 00684 // freed in there and it will go away. 00685 // 00686 00687 (*RXactContext)->RXactLog = (PRTL_RXACT_LOG)FullInformation; 00688 00689 Status = RtlAbortRXact( *RXactContext ); 00690 00691 // 00692 // This should never fail 00693 // 00694 00695 ASSERT( NT_SUCCESS( Status )); 00696 return( Status ); 00697 } else { 00698 00699 return( STATUS_RXACT_COMMIT_NECESSARY ); 00700 } 00701 00702 } else { 00703 00704 // 00705 // No log, so nothing to do here. 00706 // 00707 00708 return( STATUS_SUCCESS ); 00709 } 00710 00711 }

NTSTATUS RtlStartRXact IN PRTL_RXACT_CONTEXT  RXactContext  ) 
 

Definition at line 760 of file rxact.c.

References NULL, RTL_PAGED_CODE, RtlAllocateHeap, and RTLP_INITIAL_LOG_SIZE.

00766 : 00767 00768 This routine is used to start a new transaction in a registry sub-tree. 00769 Transactions must be serialized by the server so that only one transaction 00770 is in progress at a time. 00771 00772 Arguments: 00773 00774 RXactContext - Supplies a pointer to an RTL_RXACT_CONTEXT structure 00775 that is not currently in use. 00776 00777 Return Value: 00778 00779 STATUS_SUCCESS - Indicates the transaction was started. 00780 00781 STATUS_RXACT_INVALID_STATE - Indicates that the transaction state 00782 of the registry sub-tree is incompatible with the requested operation. 00783 For example, a request to start a new transaction while one is already 00784 in progress, or a request to apply a transaction when one is not 00785 currently in progress. This may also indicate that there is no 00786 transaction state at all for the specified registry sub-tree. 00787 00788 --*/ 00789 { 00790 PRTL_RXACT_LOG RXactLogHeader; 00791 00792 RTL_PAGED_CODE(); 00793 00794 // 00795 // Allocate in-memory log file and initialize. This implicitly 00796 // sets the state to 'transaction in progress'. 00797 // 00798 00799 if ( RXactContext->RXactLog != NULL ) { 00800 00801 // 00802 // There is already a transaction in progress for this 00803 // context. Return an error. 00804 // 00805 00806 return( STATUS_RXACT_INVALID_STATE ); 00807 } 00808 00809 RXactLogHeader = RtlAllocateHeap( RtlProcessHeap(), 0, RTLP_INITIAL_LOG_SIZE ); 00810 00811 if ( RXactLogHeader == NULL ) { 00812 return( STATUS_NO_MEMORY ); 00813 } 00814 00815 // 00816 // Fill in the log header information at the top of the 00817 // newly allocated buffer. 00818 // 00819 00820 00821 RXactLogHeader->OperationCount = 0; 00822 RXactLogHeader->LogSize = RTLP_INITIAL_LOG_SIZE; 00823 RXactLogHeader->LogSizeInUse = sizeof( RTL_RXACT_LOG ); 00824 00825 RXactContext->RXactLog = RXactLogHeader; 00826 00827 return( STATUS_SUCCESS ); 00828 00829 }

VOID RXactInitializeContext IN PRTL_RXACT_CONTEXT  RXactContext,
IN HANDLE  RootRegistryKey,
IN HANDLE  RXactKey
 

Definition at line 716 of file rxact.c.

References NULL, and TRUE.

Referenced by RtlAbortRXact(), and RtlInitializeRXact().

00724 : 00725 00726 Initializes an in-memory RXactContext structure. 00727 00728 Arguments: 00729 00730 RXactContext - Supplies a pointer to an RXact Context created 00731 by RtlInitializeRXact. 00732 00733 RootRegistryKey - Supplies the RootRegistryKey for this component. 00734 00735 RXactKey - Supplies the {RootRegistryKey}\RXactKey for this component 00736 00737 00738 Return Value: 00739 00740 None. 00741 00742 --*/ 00743 00744 { 00745 // 00746 // Initialize the RXactContext for this client 00747 // 00748 00749 RXactContext->RootRegistryKey = RootRegistryKey; 00750 RXactContext->HandlesValid = TRUE; 00751 RXactContext->RXactLog = NULL; 00752 RXactContext->RXactKey = RXactKey; 00753 00754 return; 00755 }

NTSTATUS RXactpCommit IN PRTL_RXACT_CONTEXT  RXactContext  ) 
 

Definition at line 1461 of file rxact.c.

References ASSERT, _RXACT_LOG_ENTRY::AttributeName, FALSE, INVALID_HANDLE_VALUE, _RXACT_LOG_ENTRY::KeyHandle, _RXACT_LOG_ENTRY::LogEntrySize, _RXACT_LOG_ENTRY::NewKeyValue, _RXACT_LOG_ENTRY::NewKeyValueLength, _RXACT_LOG_ENTRY::NewKeyValueType, NT_SUCCESS, NtClose(), NtDeleteKey(), NtSetValueKey(), NTSTATUS(), _RXACT_LOG_ENTRY::Operation, PRXACT_LOG_ENTRY, RXactpOpenTargetKey(), Status, _RXACT_LOG_ENTRY::SubKeyName, and TRUE.

Referenced by RtlApplyRXact(), RtlApplyRXactNoFlush(), and RtlInitializeRXact().

01467 : 01468 01469 This routine commits the operations in the operation log. 01470 01471 When all changes have been applied, the transaction state 01472 is changed to NO_TRANSACTION. 01473 01474 Arguments: 01475 01476 RXactContext - Supplies a pointer to the RXactContext structure for this 01477 subsystem's root registry key. 01478 01479 Return Value: 01480 01481 STATUS_SUCCESS - Indicates the transaction was completed. 01482 01483 01484 01485 --*/ 01486 { 01487 BOOLEAN HandlesValid; 01488 01489 HANDLE TargetKey; 01490 HANDLE RXactKey; 01491 HANDLE RootRegistryKey; 01492 01493 PRTL_RXACT_LOG RXactLog; 01494 PRXACT_LOG_ENTRY RXactLogEntry; 01495 RTL_RXACT_OPERATION Operation; 01496 01497 ULONG OperationCount; 01498 ULONG i; 01499 01500 NTSTATUS Status = STATUS_SUCCESS; 01501 NTSTATUS TmpStatus = STATUS_SUCCESS; 01502 BOOLEAN CloseTargetKey; 01503 01504 // 01505 // Extract information from the RXactContext to simplify 01506 // the code that follows 01507 // 01508 01509 RootRegistryKey = RXactContext->RootRegistryKey; 01510 RXactKey = RXactContext->RXactKey; 01511 RXactLog = RXactContext->RXactLog; 01512 01513 OperationCount = RXactLog->OperationCount; 01514 01515 HandlesValid = RXactContext->HandlesValid; 01516 01517 01518 // 01519 // Keep a pointer to the beginning of the current log entry. 01520 // 01521 01522 RXactLogEntry = (PRXACT_LOG_ENTRY)((PCHAR)RXactLog + sizeof( RTL_RXACT_LOG )); 01523 01524 01525 // 01526 // Go through and perform each operation log. Notice that some operation 01527 // logs may already have been deleted by a previous commit attempt. 01528 // So, don't get alarmed if we don't successfully open some operation 01529 // log entry keys. 01530 // 01531 01532 for ( i=0 ; i<OperationCount ; i++ ) { 01533 01534 // 01535 // Turn the self-relative offsets in the structure 01536 // back into real pointers. 01537 // 01538 01539 RXactLogEntry->SubKeyName.Buffer = (PWSTR) ((PCHAR)RXactLogEntry->SubKeyName.Buffer + 01540 (ULONG_PTR)RXactLog); 01541 01542 RXactLogEntry->AttributeName.Buffer = (PWSTR) ((PCHAR)RXactLogEntry->AttributeName.Buffer + 01543 (ULONG_PTR)RXactLog); 01544 01545 RXactLogEntry->NewKeyValue = (PVOID)((PCHAR)RXactLogEntry->NewKeyValue + (ULONG_PTR)RXactLog); 01546 01547 Operation = RXactLogEntry->Operation; 01548 01549 // 01550 // Perform this operation 01551 // 01552 01553 switch (Operation) { 01554 case RtlRXactOperationDelete: 01555 01556 // 01557 // Open the target key and delete it. 01558 // The name is relative to the RootRegistryKey. 01559 // 01560 01561 if ( ((RXactLogEntry->KeyHandle == INVALID_HANDLE_VALUE) || !HandlesValid) ) { 01562 01563 Status = RXactpOpenTargetKey( 01564 RootRegistryKey, 01565 RtlRXactOperationDelete, 01566 &RXactLogEntry->SubKeyName, 01567 &TargetKey 01568 ); 01569 01570 if ( !NT_SUCCESS(Status)) { 01571 01572 // 01573 // We must allow the object not to be found, 01574 // because we may be replaying this log after 01575 // it had been partially executed. 01576 // 01577 01578 if ( Status != STATUS_OBJECT_NAME_NOT_FOUND ) { 01579 01580 return( Status ); 01581 01582 } else { 01583 01584 break; 01585 } 01586 } 01587 01588 CloseTargetKey = TRUE; 01589 01590 } else { 01591 01592 TargetKey = RXactLogEntry->KeyHandle; 01593 CloseTargetKey = FALSE; 01594 } 01595 01596 01597 // 01598 // If this fails, then it is an error 01599 // because the key should exist at 01600 // this point. 01601 // 01602 01603 Status = NtDeleteKey( TargetKey ); 01604 01605 01606 // 01607 // Only close the target key if we opened it 01608 // 01609 01610 if ( CloseTargetKey ) { 01611 01612 TmpStatus = NtClose( TargetKey ); 01613 01614 // 01615 // If we opened this handle, then we should 01616 // be able to close it, whether it has been 01617 // deleted or not. 01618 // 01619 01620 ASSERT(NT_SUCCESS(TmpStatus)); // safe to ignore, but curious... 01621 } 01622 01623 01624 if (!NT_SUCCESS(Status)) { 01625 return(Status); 01626 } 01627 01628 break; 01629 01630 case RtlRXactOperationSetValue: 01631 01632 // 01633 // Open the target key. 01634 // The name is relative to the RootRegistryKey. 01635 // 01636 01637 if ( ((RXactLogEntry->KeyHandle == INVALID_HANDLE_VALUE) || !HandlesValid) ) { 01638 01639 Status = RXactpOpenTargetKey( 01640 RootRegistryKey, 01641 RtlRXactOperationSetValue, 01642 &RXactLogEntry->SubKeyName, 01643 &TargetKey 01644 ); 01645 01646 if ( !NT_SUCCESS(Status) ) { 01647 return(Status); 01648 } 01649 01650 CloseTargetKey = TRUE; 01651 01652 } else { 01653 01654 TargetKey = RXactLogEntry->KeyHandle; 01655 CloseTargetKey = FALSE; 01656 } 01657 01658 // 01659 // Assign to the target key's new value 01660 // 01661 01662 Status = NtSetValueKey( TargetKey, 01663 &RXactLogEntry->AttributeName, 01664 0, // TitleIndex 01665 RXactLogEntry->NewKeyValueType, 01666 RXactLogEntry->NewKeyValue, 01667 RXactLogEntry->NewKeyValueLength 01668 ); 01669 01670 // 01671 // Only close the target key if we opened it 01672 // 01673 01674 if ( CloseTargetKey ) { 01675 01676 TmpStatus = NtClose( TargetKey ); 01677 ASSERT(NT_SUCCESS(TmpStatus)); // safe to ignore, but curious... 01678 01679 } 01680 01681 if ( !NT_SUCCESS(Status) ) { 01682 return(Status); 01683 } 01684 01685 break; 01686 01687 01688 01689 default: 01690 01691 // 01692 // Unknown operation type. This should never happen. 01693 // 01694 01695 ASSERT( FALSE ); 01696 01697 return(STATUS_INVALID_PARAMETER); 01698 01699 } 01700 01701 RXactLogEntry = (PRXACT_LOG_ENTRY)((PCHAR)RXactLogEntry + RXactLogEntry->LogEntrySize); 01702 01703 } 01704 01705 // 01706 // Commit complete 01707 // 01708 01709 return( STATUS_SUCCESS ); 01710 01711 }

NTSTATUS RXactpOpenTargetKey IN HANDLE  RootRegistryKey,
IN RTL_RXACT_OPERATION  Operation,
IN PUNICODE_STRING  SubKeyName,
OUT PHANDLE  TargetKey
 

Definition at line 1717 of file rxact.c.

References NtCreateKey(), NtOpenKey(), NTSTATUS(), NULL, and Status.

Referenced by RXactpCommit().

01726 : 01727 01728 This routine opens the target registry key of an operation. 01729 01730 Arguments: 01731 01732 RootRegistryKey - A handle to the registry key within whose sub-tree 01733 a transaction is to be initialized. 01734 01735 Operation - Indicates what operation is to be performed on the target. 01736 This will effect how the target is opened. 01737 01738 OperationNameKey - A handle to the operation log sub-key 01739 containing the name of the target registry key. 01740 01741 TargetKey - Receives a handle to the target registry key. 01742 01743 Return Value: 01744 01745 STATUS_SUCCESS - Indicates the operation log entry was opened. 01746 01747 STATUS_NO_MEMORY - Ran out of heap. 01748 01749 01750 --*/ 01751 { 01752 01753 NTSTATUS Status; 01754 OBJECT_ATTRIBUTES TargetKeyAttributes; 01755 ACCESS_MASK DesiredAccess; 01756 ULONG Disposition; 01757 01758 01759 if (Operation == RtlRXactOperationDelete) { 01760 01761 DesiredAccess = DELETE; 01762 01763 InitializeObjectAttributes( 01764 &TargetKeyAttributes, 01765 SubKeyName, 01766 OBJ_CASE_INSENSITIVE, 01767 RootRegistryKey, 01768 NULL); 01769 01770 // Status = RtlpNtOpenKey( 01771 // TargetKey, 01772 // DesiredAccess, 01773 // &TargetKeyAttributes, 01774 // 0); 01775 01776 Status = NtOpenKey( TargetKey, 01777 DesiredAccess, 01778 &TargetKeyAttributes 01779 ); 01780 01781 01782 } else if (Operation == RtlRXactOperationSetValue) { 01783 01784 DesiredAccess = KEY_WRITE; 01785 01786 InitializeObjectAttributes( 01787 &TargetKeyAttributes, 01788 SubKeyName, 01789 OBJ_CASE_INSENSITIVE | OBJ_OPENIF, 01790 RootRegistryKey, 01791 NULL); 01792 01793 Status = NtCreateKey( 01794 TargetKey, 01795 DesiredAccess, 01796 &TargetKeyAttributes, 01797 0, 01798 NULL, 01799 REG_OPTION_NON_VOLATILE, 01800 &Disposition 01801 ); 01802 01803 } else { 01804 return STATUS_INVALID_PARAMETER; 01805 } 01806 01807 01808 01809 return( Status ); 01810 01811 }


Generated on Sat May 15 19:45:32 2004 for test by doxygen 1.3.7