- probe and capture parameters in NtCreateKey
- added ProbeForWriteUnicodeString and ProbeForReadUnicodeString macros
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
Modified: trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h
_____
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
--- trunk/reactos/ntoskrnl/cm/ntfunc.c 2005-10-29 15:05:37 UTC (rev
18852)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c 2005-10-29 16:00:00 UTC (rev
18853)
@@ -184,35 +184,70 @@
IN ULONG CreateOptions,
OUT PULONG Disposition)
{
- UNICODE_STRING RemainingPath;
+ UNICODE_STRING RemainingPath = {0};
+ BOOLEAN FreeRemainingPath = TRUE;
+ ULONG LocalDisposition;
PKEY_OBJECT KeyObject;
- NTSTATUS Status;
- PVOID Object;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVOID Object = NULL;
PWSTR Start;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
unsigned i;
REG_PRE_CREATE_KEY_INFORMATION PreCreateKeyInfo;
REG_POST_CREATE_KEY_INFORMATION PostCreateKeyInfo;
+ KPROCESSOR_MODE PreviousMode;
+ UNICODE_STRING CapturedClass = {0};
+ HANDLE hKey;
PAGED_CODE();
- DPRINT("NtCreateKey (Name %wZ KeyHandle 0x%p Root 0x%p)\n",
- ObjectAttributes->ObjectName,
- KeyHandle,
- ObjectAttributes->RootDirectory);
+ PreviousMode = KeGetPreviousMode();
+ if (PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForWriteHandle(KeyHandle);
+ if (Disposition != NULL)
+ {
+ ProbeForWriteUlong(Disposition);
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+
+ if (Class != NULL)
+ {
+ Status = ProbeAndCaptureUnicodeString(&CapturedClass,
+ PreviousMode,
+ Class);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+
/* Capture all the info */
DPRINT("Capturing Create Info\n");
Status = ObpCaptureObjectAttributes(ObjectAttributes,
- KeGetPreviousMode(),
+ PreviousMode,
CmiKeyType,
&ObjectCreateInfo,
&ObjectName);
if (!NT_SUCCESS(Status))
{
DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n",
Status);
- return Status;
+ goto Cleanup;
}
PostCreateKeyInfo.CompleteName = &ObjectName;
@@ -221,13 +256,12 @@
if (!NT_SUCCESS(Status))
{
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
- return Status;
+ goto Cleanup;
}
Status = ObFindObject(&ObjectCreateInfo,
&ObjectName,
- (PVOID*)&Object,
+ (PVOID*)&Object,
&RemainingPath,
CmiKeyType);
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
@@ -236,9 +270,9 @@
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey,
&PostCreateKeyInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+
DPRINT("CmpFindObject failed, Status: 0x%x\n", Status);
- return(Status);
+ goto Cleanup;
}
DPRINT("RemainingPath %wZ\n", &RemainingPath);
@@ -248,33 +282,29 @@
/* Fail if the key has been deleted */
if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
{
- ObDereferenceObject(Object);
- RtlFreeUnicodeString(&RemainingPath);
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
CmiCallRegisteredCallbacks(RegNtPostCreateKey,
&PostCreateKeyInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+
DPRINT("Object marked for delete!\n");
- return(STATUS_UNSUCCESSFUL);
+ Status = STATUS_UNSUCCESSFUL;
+ goto Cleanup;
}
- if (Disposition)
- *Disposition = REG_OPENED_EXISTING_KEY;
-
Status = ObpCreateHandle(PsGetCurrentProcess(),
Object,
DesiredAccess,
TRUE,
- KeyHandle);
+ &hKey);
DPRINT("ObpCreateHandle failed Status 0x%x\n", Status);
- ObDereferenceObject(Object);
- RtlFreeUnicodeString(&RemainingPath);
+
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey,
&PostCreateKeyInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
- return Status;
+
+ LocalDisposition = REG_OPENED_EXISTING_KEY;
+ goto SuccessReturn;
}
/* If RemainingPath contains \ we must return error
@@ -287,23 +317,23 @@
{
if (L'\\' == RemainingPath.Buffer[i])
{
- ObDereferenceObject(Object);
DPRINT1("NtCreateKey() doesn't create trees! (found \'\\\' in
remaining path: \"%wZ\"!)\n", &RemainingPath);
- RtlFreeUnicodeString(&RemainingPath);
+
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_OBJECT_NAME_NOT_FOUND;
CmiCallRegisteredCallbacks(RegNtPostCreateKey,
&PostCreateKeyInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
- return STATUS_OBJECT_NAME_NOT_FOUND;
+
+ Status = STATUS_OBJECT_NAME_NOT_FOUND;
+ goto Cleanup;
}
}
DPRINT("RemainingPath %S ParentObject 0x%p\n", RemainingPath.Buffer,
Object);
- Status = ObCreateObject(ExGetPreviousMode(),
+ Status = ObCreateObject(PreviousMode,
CmiKeyType,
NULL,
- ExGetPreviousMode(),
+ PreviousMode,
NULL,
sizeof(KEY_OBJECT),
0,
@@ -315,8 +345,8 @@
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey,
&PostCreateKeyInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
- return(Status);
+
+ goto Cleanup;
}
Status = ObInsertObject((PVOID)KeyObject,
@@ -324,17 +354,17 @@
DesiredAccess,
0,
NULL,
- KeyHandle);
+ &hKey);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(KeyObject);
- RtlFreeUnicodeString(&RemainingPath);
DPRINT1("ObInsertObject() failed!\n");
+
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey,
&PostCreateKeyInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
- return(Status);
+
+ goto Cleanup;
}
KeyObject->ParentKey = Object;
@@ -361,7 +391,7 @@
KeyObject,
&RemainingPath,
TitleIndex,
- Class,
+ &CapturedClass,
CreateOptions);
if (!NT_SUCCESS(Status))
{
@@ -370,23 +400,23 @@
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
ObDereferenceObject(KeyObject);
- ObDereferenceObject(Object);
- RtlFreeUnicodeString(&RemainingPath);
+
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
CmiCallRegisteredCallbacks(RegNtPostCreateKey,
&PostCreateKeyInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
- return STATUS_UNSUCCESSFUL;
+
+ Status = STATUS_UNSUCCESSFUL;
+ goto Cleanup;
}
if (Start == RemainingPath.Buffer)
{
KeyObject->Name = RemainingPath;
+ FreeRemainingPath = FALSE;
}
else
{
RtlpCreateUnicodeString(&KeyObject->Name, Start, NonPagedPool);
- RtlFreeUnicodeString(&RemainingPath);
}
if (KeyObject->RegistryHive == KeyObject->ParentKey->RegistryHive)
@@ -400,10 +430,7 @@
KeyObject->KeyCell->SecurityKeyOffset = -1;
/* This key must remain in memory unless it is deleted
or file is unloaded */
- ObReferenceObjectByPointer(KeyObject,
- STANDARD_RIGHTS_REQUIRED,
- NULL,
- UserMode);
+ ObReferenceObject(KeyObject);
}
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
@@ -414,19 +441,39 @@
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
-
- ObDereferenceObject(Object);
-
- if (Disposition)
- *Disposition = REG_CREATED_NEW_KEY;
-
PostCreateKeyInfo.Object = KeyObject;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
CmiSyncHives();
+
+ LocalDisposition = REG_CREATED_NEW_KEY;
+SuccessReturn:
+ _SEH_TRY
+ {
+ *KeyHandle = hKey;
+ if (Disposition != NULL)
+ {
+ *Disposition = LocalDisposition;
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+Cleanup:
+ if (Class != NULL)
+ {
+ ReleaseCapturedUnicodeString(&CapturedClass,
+ PreviousMode);
+ }
+ if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+ if (FreeRemainingPath) RtlFreeUnicodeString(&RemainingPath);
+ if (Object != NULL) ObDereferenceObject(Object);
+
return Status;
}
_____
Modified: trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h
--- trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h 2005-10-29
15:05:37 UTC (rev 18852)
+++ trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h 2005-10-29
16:00:00 UTC (rev 18853)
@@ -83,7 +83,64 @@
#define ExRaiseStatus RtlRaiseStatus
+static const UNICODE_STRING __emptyUnicodeString = {0};
+
/*
+ * NOTE: Alignment of the pointers is not verified!
+ */
+#define ProbeForWriteGenericType(Ptr, Type)
\
+ do {
\
+ if ((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) ||
\
+ (ULONG_PTR)(Ptr) + sizeof(Type) - 1 >=
(ULONG_PTR)MmUserProbeAddress) { \
+ RtlRaiseStatus (STATUS_ACCESS_VIOLATION);
\
+ }
\
+ *(volatile Type *)(Ptr) = *(volatile Type *)(Ptr);
\
+ } while (0)
+
+#define ProbeForWriteBoolean(Ptr) ProbeForWriteGenericType(Ptr,
BOOLEAN)
+#define ProbeForWriteUchar(Ptr) ProbeForWriteGenericType(Ptr, UCHAR)
+#define ProbeForWriteChar(Ptr) ProbeForWriteGenericType(Ptr, Char)
+#define ProbeForWriteUshort(Ptr) ProbeForWriteGenericType(Ptr, USHORT)
+#define ProbeForWriteShort(Ptr) ProbeForWriteGenericType(Ptr, SHORT)
+#define ProbeForWriteUlong(Ptr) ProbeForWriteGenericType(Ptr, ULONG)
+#define ProbeForWriteLong(Ptr) ProbeForWriteGenericType(Ptr, LONG)
+#define ProbeForWriteUint(Ptr) ProbeForWriteGenericType(Ptr, UINT)
+#define ProbeForWriteInt(Ptr) ProbeForWriteGenericType(Ptr, INT)
+#define ProbeForWriteUlonglong(Ptr) ProbeForWriteGenericType(Ptr,
ULONGLONG)
+#define ProbeForWriteLonglong(Ptr) ProbeForWriteGenericType(Ptr,
LONGLONG)
+#define ProbeForWriteLonglong(Ptr) ProbeForWriteGenericType(Ptr,
LONGLONG)
+#define ProbeForWritePointer(Ptr) ProbeForWriteGenericType(Ptr, PVOID)
+#define ProbeForWriteHandle(Ptr) ProbeForWriteGenericType(Ptr, HANDLE)
+#define ProbeForWriteLangid(Ptr) ProbeForWriteGenericType(Ptr, LANGID)
+#define ProbeForWriteLargeInteger(Ptr)
ProbeForWriteGenericType(&(Ptr)->QuadPart, LONGLONG)
+#define ProbeForWriteUlargeInteger(Ptr)
ProbeForWriteGenericType(&(Ptr)->QuadPart, ULONGLONG)
+#define ProbeForWriteUnicodeString(Ptr) ProbeForWriteGenericType(Ptr,
UNICODE_STRING)
+
+#define ProbeForReadGenericType(Ptr, Type, Default)
\
+ (((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) ||
\
+ (ULONG_PTR)(Ptr) + sizeof(Type) - 1 >=
(ULONG_PTR)MmUserProbeAddress) ? \
+ ExRaiseStatus (STATUS_ACCESS_VIOLATION), Default :
\
+ *(volatile Type *)(Ptr))
+
+#define ProbeForReadBoolean(Ptr) ProbeForReadGenericType(Ptr, BOOLEAN,
FALSE)
+#define ProbeForReadUchar(Ptr) ProbeForReadGenericType(Ptr, UCHAR, 0)
+#define ProbeForReadChar(Ptr) ProbeForReadGenericType(Ptr, CHAR, 0)
+#define ProbeForReadUshort(Ptr) ProbeForReadGenericType(Ptr, USHORT, 0)
+#define ProbeForReadShort(Ptr) ProbeForReadGenericType(Ptr, SHORT, 0)
+#define ProbeForReadUlong(Ptr) ProbeForReadGenericType(Ptr, ULONG, 0)
+#define ProbeForReadLong(Ptr) ProbeForReadGenericType(Ptr, LONG, 0)
+#define ProbeForReadUint(Ptr) ProbeForReadGenericType(Ptr, UINT, 0)
+#define ProbeForReadInt(Ptr) ProbeForReadGenericType(Ptr, INT, 0)
+#define ProbeForReadUlonglong(Ptr) ProbeForReadGenericType(Ptr,
ULONGLONG, 0)
+#define ProbeForReadLonglong(Ptr) ProbeForReadGenericType(Ptr,
LONGLONG, 0)
+#define ProbeForReadPointer(Ptr) ProbeForReadGenericType(Ptr, PVOID,
NULL)
+#define ProbeForReadHandle(Ptr) ProbeForReadGenericType(Ptr, HANDLE,
NULL)
+#define ProbeForReadLangid(Ptr) ProbeForReadGenericType(Ptr, LANGID, 0)
+#define ProbeForReadLargeInteger(Ptr)
((LARGE_INTEGER)ProbeForReadGenericType(&(Ptr)->QuadPart, LONGLONG, 0))
+#define ProbeForReadUlargeInteger(Ptr)
((ULARGE_INTEGER)ProbeForReadGenericType(&(Ptr)->QuadPart, ULONGLONG,
0))
+#define ProbeForReadUnicodeString(Ptr) ProbeForReadGenericType(Ptr,
UNICODE_STRING, __emptyUnicodeString)
+
+/*
* Inlined Probing Macros
*/
static __inline
@@ -102,10 +159,7 @@
{
_SEH_TRY
{
- ProbeForRead(UnsafeSrc,
- sizeof(UNICODE_STRING),
- sizeof(ULONG));
- *Dest = *UnsafeSrc;
+ *Dest = ProbeForReadUnicodeString(UnsafeSrc);
if(Dest->Buffer != NULL)
{
if (Dest->Length != 0)
@@ -175,59 +229,6 @@
}
/*
- * NOTE: Alignment of the pointers is not verified!
- */
-#define ProbeForWriteGenericType(Ptr, Type)
\
- do {
\
- if ((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) ||
\
- (ULONG_PTR)(Ptr) + sizeof(Type) - 1 >=
(ULONG_PTR)MmUserProbeAddress) { \
- RtlRaiseStatus (STATUS_ACCESS_VIOLATION);
\
- }
\
- *(volatile Type *)(Ptr) = *(volatile Type *)(Ptr);
\
- } while (0)
-
-#define ProbeForWriteBoolean(Ptr) ProbeForWriteGenericType(Ptr,
BOOLEAN)
-#define ProbeForWriteUchar(Ptr) ProbeForWriteGenericType(Ptr, UCHAR)
-#define ProbeForWriteChar(Ptr) ProbeForWriteGenericType(Ptr, Char)
-#define ProbeForWriteUshort(Ptr) ProbeForWriteGenericType(Ptr, USHORT)
-#define ProbeForWriteShort(Ptr) ProbeForWriteGenericType(Ptr, SHORT)
-#define ProbeForWriteUlong(Ptr) ProbeForWriteGenericType(Ptr, ULONG)
-#define ProbeForWriteLong(Ptr) ProbeForWriteGenericType(Ptr, LONG)
-#define ProbeForWriteUint(Ptr) ProbeForWriteGenericType(Ptr, UINT)
-#define ProbeForWriteInt(Ptr) ProbeForWriteGenericType(Ptr, INT)
-#define ProbeForWriteUlonglong(Ptr) ProbeForWriteGenericType(Ptr,
ULONGLONG)
-#define ProbeForWriteLonglong(Ptr) ProbeForWriteGenericType(Ptr,
LONGLONG)
-#define ProbeForWriteLonglong(Ptr) ProbeForWriteGenericType(Ptr,
LONGLONG)
-#define ProbeForWritePointer(Ptr) ProbeForWriteGenericType(Ptr, PVOID)
-#define ProbeForWriteHandle(Ptr) ProbeForWriteGenericType(Ptr, HANDLE)
-#define ProbeForWriteLangid(Ptr) ProbeForWriteGenericType(Ptr, LANGID)
-#define ProbeForWriteLargeInteger(Ptr)
ProbeForWriteGenericType(&(Ptr)->QuadPart, LONGLONG)
-#define ProbeForWriteUlargeInteger(Ptr)
ProbeForWriteGenericType(&(Ptr)->QuadPart, ULONGLONG)
-
-#define ProbeForReadGenericType(Ptr, Type, Default)
\
- (((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) ||
\
- (ULONG_PTR)(Ptr) + sizeof(Type) - 1 >=
(ULONG_PTR)MmUserProbeAddress) ? \
- ExRaiseStatus (STATUS_ACCESS_VIOLATION), Default :
\
- *(volatile Type *)(Ptr))
-
-#define ProbeForReadBoolean(Ptr) ProbeForReadGenericType(Ptr, BOOLEAN,
FALSE)
-#define ProbeForReadUchar(Ptr) ProbeForReadGenericType(Ptr, UCHAR, 0)
-#define ProbeForReadChar(Ptr) ProbeForReadGenericType(Ptr, CHAR, 0)
-#define ProbeForReadUshort(Ptr) ProbeForReadGenericType(Ptr, USHORT, 0)
-#define ProbeForReadShort(Ptr) ProbeForReadGenericType(Ptr, SHORT, 0)
-#define ProbeForReadUlong(Ptr) ProbeForReadGenericType(Ptr, ULONG, 0)
-#define ProbeForReadLong(Ptr) ProbeForReadGenericType(Ptr, LONG, 0)
-#define ProbeForReadUint(Ptr) ProbeForReadGenericType(Ptr, UINT, 0)
-#define ProbeForReadInt(Ptr) ProbeForReadGenericType(Ptr, INT, 0)
-#define ProbeForReadUlonglong(Ptr) ProbeForReadGenericType(Ptr,
ULONGLONG, 0)
-#define ProbeForReadLonglong(Ptr) ProbeForReadGenericType(Ptr,
LONGLONG, 0)
-#define ProbeForReadPointer(Ptr) ProbeForReadGenericType(Ptr, PVOID,
NULL)
-#define ProbeForReadHandle(Ptr) ProbeForReadGenericType(Ptr, HANDLE,
NULL)
-#define ProbeForReadLangid(Ptr) ProbeForReadGenericType(Ptr, LANGID, 0)
-#define ProbeForReadLargeInteger(Ptr)
((LARGE_INTEGER)ProbeForReadGenericType(&(Ptr)->QuadPart, LONGLONG, 0))
-#define ProbeForReadUlargeInteger(Ptr)
((ULARGE_INTEGER)ProbeForReadGenericType(&(Ptr)->QuadPart, ULONGLONG,
0))
-
-/*
* generic information class probing code
*/