- probe and capture parameters in NtCreateKey

- added ProbeForWriteUnicodeString and ProbeForReadUnicodeString macros

svn path=/trunk/; revision=18853
This commit is contained in:
Thomas Bluemel 2005-10-29 16:00:00 +00:00
parent bffa3474f4
commit 006d0bc6d7
2 changed files with 161 additions and 113 deletions

View file

@ -184,35 +184,70 @@ NtCreateKey(OUT PHANDLE KeyHandle,
IN ULONG CreateOptions, IN ULONG CreateOptions,
OUT PULONG Disposition) OUT PULONG Disposition)
{ {
UNICODE_STRING RemainingPath; UNICODE_STRING RemainingPath = {0};
BOOLEAN FreeRemainingPath = TRUE;
ULONG LocalDisposition;
PKEY_OBJECT KeyObject; PKEY_OBJECT KeyObject;
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
PVOID Object; PVOID Object = NULL;
PWSTR Start; PWSTR Start;
UNICODE_STRING ObjectName; UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo; OBJECT_CREATE_INFORMATION ObjectCreateInfo;
unsigned i; unsigned i;
REG_PRE_CREATE_KEY_INFORMATION PreCreateKeyInfo; REG_PRE_CREATE_KEY_INFORMATION PreCreateKeyInfo;
REG_POST_CREATE_KEY_INFORMATION PostCreateKeyInfo; REG_POST_CREATE_KEY_INFORMATION PostCreateKeyInfo;
KPROCESSOR_MODE PreviousMode;
UNICODE_STRING CapturedClass = {0};
HANDLE hKey;
PAGED_CODE(); PAGED_CODE();
DPRINT("NtCreateKey (Name %wZ KeyHandle 0x%p Root 0x%p)\n", PreviousMode = KeGetPreviousMode();
ObjectAttributes->ObjectName,
KeyHandle, if (PreviousMode != KernelMode)
ObjectAttributes->RootDirectory); {
_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 */ /* Capture all the info */
DPRINT("Capturing Create Info\n"); DPRINT("Capturing Create Info\n");
Status = ObpCaptureObjectAttributes(ObjectAttributes, Status = ObpCaptureObjectAttributes(ObjectAttributes,
KeGetPreviousMode(), PreviousMode,
CmiKeyType, CmiKeyType,
&ObjectCreateInfo, &ObjectCreateInfo,
&ObjectName); &ObjectName);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status); DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
return Status; goto Cleanup;
} }
PostCreateKeyInfo.CompleteName = &ObjectName; PostCreateKeyInfo.CompleteName = &ObjectName;
@ -221,13 +256,12 @@ NtCreateKey(OUT PHANDLE KeyHandle,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ObpReleaseCapturedAttributes(&ObjectCreateInfo); ObpReleaseCapturedAttributes(&ObjectCreateInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); goto Cleanup;
return Status;
} }
Status = ObFindObject(&ObjectCreateInfo, Status = ObFindObject(&ObjectCreateInfo,
&ObjectName, &ObjectName,
(PVOID*)&Object, (PVOID*)&Object,
&RemainingPath, &RemainingPath,
CmiKeyType); CmiKeyType);
ObpReleaseCapturedAttributes(&ObjectCreateInfo); ObpReleaseCapturedAttributes(&ObjectCreateInfo);
@ -236,9 +270,9 @@ NtCreateKey(OUT PHANDLE KeyHandle,
PostCreateKeyInfo.Object = NULL; PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status; PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
DPRINT("CmpFindObject failed, Status: 0x%x\n", Status); DPRINT("CmpFindObject failed, Status: 0x%x\n", Status);
return(Status); goto Cleanup;
} }
DPRINT("RemainingPath %wZ\n", &RemainingPath); DPRINT("RemainingPath %wZ\n", &RemainingPath);
@ -248,33 +282,29 @@ NtCreateKey(OUT PHANDLE KeyHandle,
/* Fail if the key has been deleted */ /* Fail if the key has been deleted */
if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE) if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
{ {
ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath);
PostCreateKeyInfo.Object = NULL; PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL; PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
DPRINT("Object marked for delete!\n");
return(STATUS_UNSUCCESSFUL);
}
if (Disposition) DPRINT("Object marked for delete!\n");
*Disposition = REG_OPENED_EXISTING_KEY; Status = STATUS_UNSUCCESSFUL;
goto Cleanup;
}
Status = ObpCreateHandle(PsGetCurrentProcess(), Status = ObpCreateHandle(PsGetCurrentProcess(),
Object, Object,
DesiredAccess, DesiredAccess,
TRUE, TRUE,
KeyHandle); &hKey);
DPRINT("ObpCreateHandle failed Status 0x%x\n", Status); DPRINT("ObpCreateHandle failed Status 0x%x\n", Status);
ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath);
PostCreateKeyInfo.Object = NULL; PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status; PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); 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 /* If RemainingPath contains \ we must return error
@ -287,23 +317,23 @@ NtCreateKey(OUT PHANDLE KeyHandle,
{ {
if (L'\\' == RemainingPath.Buffer[i]) if (L'\\' == RemainingPath.Buffer[i])
{ {
ObDereferenceObject(Object);
DPRINT1("NtCreateKey() doesn't create trees! (found \'\\\' in remaining path: \"%wZ\"!)\n", &RemainingPath); DPRINT1("NtCreateKey() doesn't create trees! (found \'\\\' in remaining path: \"%wZ\"!)\n", &RemainingPath);
RtlFreeUnicodeString(&RemainingPath);
PostCreateKeyInfo.Object = NULL; PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_OBJECT_NAME_NOT_FOUND; PostCreateKeyInfo.Status = STATUS_OBJECT_NAME_NOT_FOUND;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); 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); DPRINT("RemainingPath %S ParentObject 0x%p\n", RemainingPath.Buffer, Object);
Status = ObCreateObject(ExGetPreviousMode(), Status = ObCreateObject(PreviousMode,
CmiKeyType, CmiKeyType,
NULL, NULL,
ExGetPreviousMode(), PreviousMode,
NULL, NULL,
sizeof(KEY_OBJECT), sizeof(KEY_OBJECT),
0, 0,
@ -315,8 +345,8 @@ NtCreateKey(OUT PHANDLE KeyHandle,
PostCreateKeyInfo.Object = NULL; PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status; PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return(Status); goto Cleanup;
} }
Status = ObInsertObject((PVOID)KeyObject, Status = ObInsertObject((PVOID)KeyObject,
@ -324,17 +354,17 @@ NtCreateKey(OUT PHANDLE KeyHandle,
DesiredAccess, DesiredAccess,
0, 0,
NULL, NULL,
KeyHandle); &hKey);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
RtlFreeUnicodeString(&RemainingPath);
DPRINT1("ObInsertObject() failed!\n"); DPRINT1("ObInsertObject() failed!\n");
PostCreateKeyInfo.Object = NULL; PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status; PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return(Status); goto Cleanup;
} }
KeyObject->ParentKey = Object; KeyObject->ParentKey = Object;
@ -361,7 +391,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
KeyObject, KeyObject,
&RemainingPath, &RemainingPath,
TitleIndex, TitleIndex,
Class, &CapturedClass,
CreateOptions); CreateOptions);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -370,23 +400,23 @@ NtCreateKey(OUT PHANDLE KeyHandle,
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath);
PostCreateKeyInfo.Object = NULL; PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL; PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
goto Cleanup;
} }
if (Start == RemainingPath.Buffer) if (Start == RemainingPath.Buffer)
{ {
KeyObject->Name = RemainingPath; KeyObject->Name = RemainingPath;
FreeRemainingPath = FALSE;
} }
else else
{ {
RtlpCreateUnicodeString(&KeyObject->Name, Start, NonPagedPool); RtlpCreateUnicodeString(&KeyObject->Name, Start, NonPagedPool);
RtlFreeUnicodeString(&RemainingPath);
} }
if (KeyObject->RegistryHive == KeyObject->ParentKey->RegistryHive) if (KeyObject->RegistryHive == KeyObject->ParentKey->RegistryHive)
@ -400,10 +430,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
KeyObject->KeyCell->SecurityKeyOffset = -1; KeyObject->KeyCell->SecurityKeyOffset = -1;
/* This key must remain in memory unless it is deleted /* This key must remain in memory unless it is deleted
or file is unloaded */ or file is unloaded */
ObReferenceObjectByPointer(KeyObject, ObReferenceObject(KeyObject);
STANDARD_RIGHTS_REQUIRED,
NULL,
UserMode);
} }
CmiAddKeyToList(KeyObject->ParentKey, KeyObject); CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
@ -414,18 +441,38 @@ NtCreateKey(OUT PHANDLE KeyHandle,
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
ObDereferenceObject(Object);
if (Disposition)
*Disposition = REG_CREATED_NEW_KEY;
PostCreateKeyInfo.Object = KeyObject; PostCreateKeyInfo.Object = KeyObject;
PostCreateKeyInfo.Status = Status; PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
CmiSyncHives(); 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; return Status;
} }

View file

@ -83,6 +83,63 @@ RtlpLogException(IN PEXCEPTION_RECORD ExceptionRecord,
#define ExRaiseStatus RtlRaiseStatus #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 * Inlined Probing Macros
*/ */
@ -102,10 +159,7 @@ ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest,
{ {
_SEH_TRY _SEH_TRY
{ {
ProbeForRead(UnsafeSrc, *Dest = ProbeForReadUnicodeString(UnsafeSrc);
sizeof(UNICODE_STRING),
sizeof(ULONG));
*Dest = *UnsafeSrc;
if(Dest->Buffer != NULL) if(Dest->Buffer != NULL)
{ {
if (Dest->Length != 0) if (Dest->Length != 0)
@ -174,59 +228,6 @@ ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString,
} }
} }
/*
* 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 * generic information class probing code
*/ */