Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenprobe.h
Go to the documentation of this file.
00001 #ifndef INCLUDE_REACTOS_CAPTURE_H 00002 #define INCLUDE_REACTOS_CAPTURE_H 00003 00004 #if ! defined(_NTOSKRNL_) && ! defined(_WIN32K_) 00005 #error Header intended for use by NTOSKRNL/WIN32K only! 00006 #endif 00007 00008 static const UNICODE_STRING __emptyUnicodeString = {0, 0, NULL}; 00009 static const LARGE_INTEGER __emptyLargeInteger = {{0, 0}}; 00010 static const ULARGE_INTEGER __emptyULargeInteger = {{0, 0}}; 00011 static const IO_STATUS_BLOCK __emptyIoStatusBlock = {{0}, 0}; 00012 00013 #if defined(_WIN32K_) 00014 static const LARGE_STRING __emptyLargeString = {0, 0, 0, NULL}; 00015 #endif 00016 00017 /* 00018 * NOTE: Alignment of the pointers is not verified! 00019 */ 00020 #define ProbeForWriteGenericType(Ptr, Type) \ 00021 do { \ 00022 if ((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) || \ 00023 (ULONG_PTR)(Ptr) + sizeof(Type) - 1 >= (ULONG_PTR)MmUserProbeAddress) { \ 00024 ExRaiseAccessViolation(); \ 00025 } \ 00026 *(volatile Type *)(Ptr) = *(volatile Type *)(Ptr); \ 00027 } while (0) 00028 00029 #define ProbeForWriteBoolean(Ptr) ProbeForWriteGenericType(Ptr, BOOLEAN) 00030 #define ProbeForWriteUchar(Ptr) ProbeForWriteGenericType(Ptr, UCHAR) 00031 #define ProbeForWriteChar(Ptr) ProbeForWriteGenericType(Ptr, CHAR) 00032 #define ProbeForWriteUshort(Ptr) ProbeForWriteGenericType(Ptr, USHORT) 00033 #define ProbeForWriteShort(Ptr) ProbeForWriteGenericType(Ptr, SHORT) 00034 #define ProbeForWriteUlong(Ptr) ProbeForWriteGenericType(Ptr, ULONG) 00035 #define ProbeForWriteLong(Ptr) ProbeForWriteGenericType(Ptr, LONG) 00036 #define ProbeForWriteUint(Ptr) ProbeForWriteGenericType(Ptr, UINT) 00037 #define ProbeForWriteInt(Ptr) ProbeForWriteGenericType(Ptr, INT) 00038 #define ProbeForWriteUlonglong(Ptr) ProbeForWriteGenericType(Ptr, ULONGLONG) 00039 #define ProbeForWriteLonglong(Ptr) ProbeForWriteGenericType(Ptr, LONGLONG) 00040 #define ProbeForWritePointer(Ptr) ProbeForWriteGenericType(Ptr, PVOID) 00041 #define ProbeForWriteHandle(Ptr) ProbeForWriteGenericType(Ptr, HANDLE) 00042 #define ProbeForWriteLangid(Ptr) ProbeForWriteGenericType(Ptr, LANGID) 00043 #define ProbeForWriteSize_t(Ptr) ProbeForWriteGenericType(Ptr, SIZE_T) 00044 #define ProbeForWriteLargeInteger(Ptr) ProbeForWriteGenericType(&((PLARGE_INTEGER)Ptr)->QuadPart, LONGLONG) 00045 #define ProbeForWriteUlargeInteger(Ptr) ProbeForWriteGenericType(&((PULARGE_INTEGER)Ptr)->QuadPart, ULONGLONG) 00046 #define ProbeForWriteUnicodeString(Ptr) ProbeForWriteGenericType((PUNICODE_STRING)Ptr, UNICODE_STRING) 00047 #if defined(_WIN32K_) 00048 #define ProbeForWriteLargeString(Ptr) ProbeForWriteGenericType((PLARGE_STRING)Ptr, LARGE_STRING) 00049 #endif 00050 #define ProbeForWriteIoStatusBlock(Ptr) ProbeForWriteGenericType((PIO_STATUS_BLOCK)Ptr, IO_STATUS_BLOCK) 00051 00052 #define ProbeForReadGenericType(Ptr, Type, Default) \ 00053 (((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) || \ 00054 (ULONG_PTR)(Ptr) + sizeof(Type) - 1 >= (ULONG_PTR)MmUserProbeAddress) ? \ 00055 ExRaiseAccessViolation(), Default : \ 00056 *(const volatile Type *)(Ptr)) 00057 00058 #define ProbeForReadBoolean(Ptr) ProbeForReadGenericType(Ptr, BOOLEAN, FALSE) 00059 #define ProbeForReadUchar(Ptr) ProbeForReadGenericType(Ptr, UCHAR, 0) 00060 #define ProbeForReadChar(Ptr) ProbeForReadGenericType(Ptr, CHAR, 0) 00061 #define ProbeForReadUshort(Ptr) ProbeForReadGenericType(Ptr, USHORT, 0) 00062 #define ProbeForReadShort(Ptr) ProbeForReadGenericType(Ptr, SHORT, 0) 00063 #define ProbeForReadUlong(Ptr) ProbeForReadGenericType(Ptr, ULONG, 0) 00064 #define ProbeForReadLong(Ptr) ProbeForReadGenericType(Ptr, LONG, 0) 00065 #define ProbeForReadUint(Ptr) ProbeForReadGenericType(Ptr, UINT, 0) 00066 #define ProbeForReadInt(Ptr) ProbeForReadGenericType(Ptr, INT, 0) 00067 #define ProbeForReadUlonglong(Ptr) ProbeForReadGenericType(Ptr, ULONGLONG, 0) 00068 #define ProbeForReadLonglong(Ptr) ProbeForReadGenericType(Ptr, LONGLONG, 0) 00069 #define ProbeForReadPointer(Ptr) ProbeForReadGenericType(Ptr, PVOID, NULL) 00070 #define ProbeForReadHandle(Ptr) ProbeForReadGenericType(Ptr, HANDLE, NULL) 00071 #define ProbeForReadLangid(Ptr) ProbeForReadGenericType(Ptr, LANGID, 0) 00072 #define ProbeForReadSize_t(Ptr) ProbeForReadGenericType(Ptr, SIZE_T, 0) 00073 #define ProbeForReadLargeInteger(Ptr) ProbeForReadGenericType((const LARGE_INTEGER *)(Ptr), LARGE_INTEGER, __emptyLargeInteger) 00074 #define ProbeForReadUlargeInteger(Ptr) ProbeForReadGenericType((const ULARGE_INTEGER *)(Ptr), ULARGE_INTEGER, __emptyULargeInteger) 00075 #define ProbeForReadUnicodeString(Ptr) ProbeForReadGenericType((const UNICODE_STRING *)(Ptr), UNICODE_STRING, __emptyUnicodeString) 00076 #if defined(_WIN32K_) 00077 #define ProbeForReadLargeString(Ptr) ProbeForReadGenericType((const LARGE_STRING *)(Ptr), LARGE_STRING, __emptyLargeString) 00078 #endif 00079 #define ProbeForReadIoStatusBlock(Ptr) ProbeForReadGenericType((const IO_STATUS_BLOCK *)(Ptr), IO_STATUS_BLOCK, __emptyIoStatusBlock) 00080 00081 #define ProbeAndZeroHandle(Ptr) \ 00082 do { \ 00083 if ((ULONG_PTR)(Ptr) + sizeof(HANDLE) - 1 < (ULONG_PTR)(Ptr) || \ 00084 (ULONG_PTR)(Ptr) + sizeof(HANDLE) - 1 >= (ULONG_PTR)MmUserProbeAddress) { \ 00085 ExRaiseAccessViolation(); \ 00086 } \ 00087 *(volatile HANDLE *)(Ptr) = NULL; \ 00088 } while (0) 00089 00090 /* 00091 * Inlined Probing Macros 00092 */ 00093 00094 #if defined(_WIN32K_) 00095 static __inline 00096 VOID 00097 ProbeArrayForRead(IN const VOID *ArrayPtr, 00098 IN ULONG ItemSize, 00099 IN ULONG ItemCount, 00100 IN ULONG Alignment) 00101 { 00102 ULONG ArraySize; 00103 00104 /* Check for integer overflow */ 00105 ArraySize = ItemSize * ItemCount; 00106 if (ArraySize / ItemSize != ItemCount) 00107 { 00108 ExRaiseStatus(STATUS_INVALID_PARAMETER); 00109 } 00110 00111 /* Probe the array */ 00112 ProbeForRead(ArrayPtr, 00113 ArraySize, 00114 Alignment); 00115 } 00116 00117 static __inline 00118 VOID 00119 ProbeArrayForWrite(IN OUT PVOID ArrayPtr, 00120 IN ULONG ItemSize, 00121 IN ULONG ItemCount, 00122 IN ULONG Alignment) 00123 { 00124 ULONG ArraySize; 00125 00126 /* Check for integer overflow */ 00127 ArraySize = ItemSize * ItemCount; 00128 if (ArraySize / ItemSize != ItemCount) 00129 { 00130 ExRaiseStatus(STATUS_INVALID_PARAMETER); 00131 } 00132 00133 /* Probe the array */ 00134 ProbeForWrite(ArrayPtr, 00135 ArraySize, 00136 Alignment); 00137 } 00138 #endif /* _WIN32K_ */ 00139 00140 static __inline 00141 NTSTATUS 00142 ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, 00143 IN KPROCESSOR_MODE CurrentMode, 00144 IN const UNICODE_STRING *UnsafeSrc) 00145 { 00146 NTSTATUS Status = STATUS_SUCCESS; 00147 WCHAR *Buffer = NULL; 00148 ASSERT(Dest != NULL); 00149 00150 /* Probe the structure and buffer*/ 00151 if(CurrentMode != KernelMode) 00152 { 00153 _SEH2_TRY 00154 { 00155 *Dest = ProbeForReadUnicodeString(UnsafeSrc); 00156 if(Dest->Buffer != NULL) 00157 { 00158 if (Dest->Length != 0) 00159 { 00160 ProbeForRead(Dest->Buffer, 00161 Dest->Length, 00162 sizeof(WCHAR)); 00163 00164 /* Allocate space for the buffer */ 00165 Buffer = ExAllocatePoolWithTag(PagedPool, 00166 Dest->Length + sizeof(WCHAR), 00167 'RTSU'); 00168 if (Buffer == NULL) 00169 { 00170 Status = STATUS_INSUFFICIENT_RESOURCES; 00171 _SEH2_LEAVE; 00172 } 00173 00174 /* Copy it */ 00175 RtlCopyMemory(Buffer, Dest->Buffer, Dest->Length); 00176 Buffer[Dest->Length / sizeof(WCHAR)] = UNICODE_NULL; 00177 00178 /* Set it as the buffer */ 00179 Dest->Buffer = Buffer; 00180 Dest->MaximumLength = Dest->Length + sizeof(WCHAR); 00181 } 00182 else 00183 { 00184 /* sanitize structure */ 00185 Dest->MaximumLength = 0; 00186 Dest->Buffer = NULL; 00187 } 00188 } 00189 else 00190 { 00191 /* sanitize structure */ 00192 Dest->Length = 0; 00193 Dest->MaximumLength = 0; 00194 } 00195 } 00196 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00197 { 00198 /* Free allocated resources and zero the destination string */ 00199 if (Buffer != NULL) 00200 { 00201 ExFreePool(Buffer); 00202 } 00203 Dest->Length = 0; 00204 Dest->MaximumLength = 0; 00205 Dest->Buffer = NULL; 00206 00207 /* Return the error code */ 00208 Status = _SEH2_GetExceptionCode(); 00209 } 00210 _SEH2_END; 00211 } 00212 else 00213 { 00214 /* Just copy the UNICODE_STRING structure, don't allocate new memory! 00215 We trust the caller to supply valid pointers and data. */ 00216 *Dest = *UnsafeSrc; 00217 } 00218 00219 /* Return */ 00220 return Status; 00221 } 00222 00223 static __inline 00224 VOID 00225 ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, 00226 IN KPROCESSOR_MODE CurrentMode) 00227 { 00228 if(CurrentMode != KernelMode && CapturedString->Buffer != NULL) 00229 { 00230 ExFreePool(CapturedString->Buffer); 00231 } 00232 } 00233 00234 #endif /* INCLUDE_REACTOS_CAPTURE_H */ Generated on Sun May 27 2012 04:33:17 for ReactOS by
1.7.6.1
|