385 lines
10 KiB
C
385 lines
10 KiB
C
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
process.c
|
|
|
|
Abstract:
|
|
|
|
Process management routines
|
|
|
|
--*/
|
|
|
|
#include "basedll.h"
|
|
#pragma hdrstop
|
|
|
|
BOOL
|
|
WINAPI
|
|
IsBadReadPtr(
|
|
CONST VOID *lp,
|
|
UINT_PTR cb
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function verifies that the range of memory specified by the
|
|
input parameters can be read by the calling process.
|
|
|
|
If the entire range of memory is accessible, then a value of FALSE
|
|
is returned; otherwise, a value of TRUE is returned.
|
|
|
|
Note that since Win32 is a pre-emptive multi-tasking environment,
|
|
the results of this test are only meaningful if the other threads in
|
|
the process do not manipulate the range of memory being tested by
|
|
this call. Even after a pointer validation, an application should
|
|
use the structured exception handling capabilities present in the
|
|
system to guard access through pointers that it does not control.
|
|
|
|
Arguments:
|
|
|
|
lp - Supplies the base address of the memory that is to be checked
|
|
for read access.
|
|
|
|
cb - Supplies the length in bytes to be checked.
|
|
|
|
Return Value:
|
|
|
|
TRUE - Some portion of the specified range of memory is not accessible
|
|
for read access.
|
|
|
|
FALSE - All pages within the specified range have been successfully
|
|
read.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PSZ EndAddress;
|
|
PSZ StartAddress;
|
|
|
|
//
|
|
// If the structure has zero length, then do not probe the structure for
|
|
// read accessibility or alignment.
|
|
//
|
|
|
|
if (cb != 0) {
|
|
|
|
//
|
|
// If it is a NULL pointer just return TRUE, they are always bad
|
|
//
|
|
if (lp == NULL) {
|
|
return TRUE;
|
|
}
|
|
|
|
StartAddress = (PSZ)lp;
|
|
|
|
//
|
|
// Compute the ending address of the structure and probe for
|
|
// read accessibility.
|
|
//
|
|
|
|
EndAddress = StartAddress + cb - 1;
|
|
if ( EndAddress < StartAddress ) {
|
|
return TRUE;
|
|
}
|
|
else {
|
|
try {
|
|
*(volatile CHAR *)StartAddress;
|
|
StartAddress = (PCHAR)((ULONG_PTR)StartAddress & (~((LONG)PAGE_SIZE - 1)));
|
|
EndAddress = (PCHAR)((ULONG_PTR)EndAddress & (~((LONG)PAGE_SIZE - 1)));
|
|
while (StartAddress != EndAddress) {
|
|
StartAddress = StartAddress + PAGE_SIZE;
|
|
*(volatile CHAR *)StartAddress;
|
|
}
|
|
}
|
|
except(EXCEPTION_EXECUTE_HANDLER) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
IsBadWritePtr(
|
|
LPVOID lp,
|
|
UINT_PTR cb
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function verifies that the range of memory specified by the
|
|
input parameters can be written by the calling process.
|
|
|
|
If the entire range of memory is accessible, then a value of FALSE
|
|
is returned; otherwise, a value of TRUE is returned.
|
|
|
|
Note that since Win32 is a pre-emptive multi-tasking environment,
|
|
the results of this test are only meaningful if the other threads in
|
|
the process do not manipulate the range of memory being tested by
|
|
this call. Even after a pointer validation, an application should
|
|
use the structured exception handling capabilities present in the
|
|
system to guard access through pointers that it does not control.
|
|
|
|
Also not that implementations are free to do a write test by reading
|
|
a value and then writing it back.
|
|
|
|
Arguments:
|
|
|
|
lp - Supplies the base address of the memory that is to be checked
|
|
for write access.
|
|
|
|
cb - Supplies the length in bytes to be checked.
|
|
|
|
Return Value:
|
|
|
|
TRUE - Some portion of the specified range of memory is not accessible
|
|
for write access.
|
|
|
|
FALSE - All pages within the specified range have been successfully
|
|
written.
|
|
|
|
--*/
|
|
{
|
|
PSZ EndAddress;
|
|
PSZ StartAddress;
|
|
|
|
//
|
|
// If the structure has zero length, then do not probe the structure for
|
|
// write accessibility.
|
|
//
|
|
|
|
if (cb != 0) {
|
|
|
|
//
|
|
// If it is a NULL pointer just return TRUE, they are always bad
|
|
//
|
|
if (lp == NULL) {
|
|
return TRUE;
|
|
}
|
|
|
|
StartAddress = (PCHAR)lp;
|
|
|
|
//
|
|
// Compute the ending address of the structure and probe for
|
|
// write accessibility.
|
|
//
|
|
|
|
EndAddress = StartAddress + cb - 1;
|
|
if ( EndAddress < StartAddress ) {
|
|
return TRUE;
|
|
}
|
|
else {
|
|
try {
|
|
*(volatile CHAR *)StartAddress = *(volatile CHAR *)StartAddress;
|
|
StartAddress = (PCHAR)((ULONG_PTR)StartAddress & (~((LONG)PAGE_SIZE - 1)));
|
|
EndAddress = (PCHAR)((ULONG_PTR)EndAddress & (~((LONG)PAGE_SIZE - 1)));
|
|
while (StartAddress != EndAddress) {
|
|
StartAddress = StartAddress + PAGE_SIZE;
|
|
*(volatile CHAR *)StartAddress = *(volatile CHAR *)StartAddress;
|
|
}
|
|
}
|
|
except(EXCEPTION_EXECUTE_HANDLER) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
IsBadCodePtr(
|
|
FARPROC lpfn
|
|
)
|
|
|
|
/*++
|
|
|
|
Same as IsBadReadPtr with a length of 1
|
|
|
|
--*/
|
|
|
|
{
|
|
return IsBadReadPtr((LPVOID)lpfn,1);
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
IsBadStringPtrW(
|
|
LPCWSTR lpsz,
|
|
UINT_PTR cchMax
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function verifies that the range of memory specified by the
|
|
input parameters can be read by the calling process.
|
|
|
|
The range is the smaller of the number of bytes covered by the
|
|
specified NULL terminated UNICODE string, or the number of bytes
|
|
specified by cchMax.
|
|
|
|
If the entire range of memory is accessible, then a value of FALSE
|
|
is returned; otherwise, a value of TRUE is returned.
|
|
|
|
Note that since Win32 is a pre-emptive multi-tasking environment,
|
|
the results of this test are only meaningful if the other threads in
|
|
the process do not manipulate the range of memory being tested by
|
|
this call. Even after a pointer validation, an application should
|
|
use the structured exception handling capabilities present in the
|
|
system to guard access through pointers that it does not control.
|
|
|
|
Arguments:
|
|
|
|
lpsz - Supplies the base address of the memory that is to be checked
|
|
for read access.
|
|
|
|
cchMax - Supplies the length in characters to be checked.
|
|
|
|
Return Value:
|
|
|
|
TRUE - Some portion of the specified range of memory is not accessible
|
|
for read access.
|
|
|
|
FALSE - All pages within the specified range have been successfully
|
|
read.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
LPCWSTR EndAddress;
|
|
LPCWSTR StartAddress;
|
|
WCHAR c;
|
|
|
|
//
|
|
// If the structure has zero length, then do not probe the structure for
|
|
// read accessibility.
|
|
//
|
|
|
|
if (cchMax != 0) {
|
|
|
|
//
|
|
// If it is a NULL pointer just return TRUE, they are always bad
|
|
//
|
|
if (lpsz == NULL) {
|
|
return TRUE;
|
|
}
|
|
|
|
StartAddress = lpsz;
|
|
|
|
//
|
|
// Compute the ending address of the structure and probe for
|
|
// read accessibility.
|
|
//
|
|
|
|
EndAddress = (LPCWSTR)((PSZ)StartAddress + (cchMax*sizeof(WCHAR)) - sizeof(WCHAR));
|
|
try {
|
|
c = *(volatile WCHAR *)StartAddress;
|
|
while ( c && StartAddress != EndAddress ) {
|
|
StartAddress++;
|
|
c = *(volatile WCHAR *)StartAddress;
|
|
}
|
|
}
|
|
except(EXCEPTION_EXECUTE_HANDLER) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
IsBadStringPtrA(
|
|
LPCSTR lpsz,
|
|
UINT_PTR cchMax
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function verifies that the range of memory specified by the
|
|
input parameters can be read by the calling process.
|
|
|
|
The range is the smaller of the number of bytes covered by the
|
|
specified NULL terminated UNICODE string, or the number of bytes
|
|
specified by cchMax.
|
|
|
|
If the entire range of memory is accessible, then a value of FALSE
|
|
is returned; otherwise, a value of TRUE is returned.
|
|
|
|
Note that since Win32 is a pre-emptive multi-tasking environment,
|
|
the results of this test are only meaningful if the other threads in
|
|
the process do not manipulate the range of memory being tested by
|
|
this call. Even after a pointer validation, an application should
|
|
use the structured exception handling capabilities present in the
|
|
system to guard access through pointers that it does not control.
|
|
|
|
Arguments:
|
|
|
|
lpsz - Supplies the base address of the memory that is to be checked
|
|
for read access.
|
|
|
|
cchMax - Supplies the length in characters to be checked.
|
|
|
|
Return Value:
|
|
|
|
TRUE - Some portion of the specified range of memory is not accessible
|
|
for read access.
|
|
|
|
FALSE - All pages within the specified range have been successfully
|
|
read.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
LPCSTR EndAddress;
|
|
LPCSTR StartAddress;
|
|
CHAR c;
|
|
|
|
//
|
|
// If the structure has zero length, then do not probe the structure for
|
|
// read accessibility.
|
|
//
|
|
|
|
if (cchMax != 0) {
|
|
|
|
//
|
|
// If it is a NULL pointer just return TRUE, they are always bad
|
|
//
|
|
if (lpsz == NULL) {
|
|
return TRUE;
|
|
}
|
|
|
|
StartAddress = lpsz;
|
|
|
|
//
|
|
// Compute the ending address of the structure and probe for
|
|
// read accessibility.
|
|
//
|
|
|
|
EndAddress = (LPCSTR)((PSZ)StartAddress + (cchMax*sizeof(CHAR)) - sizeof(CHAR));
|
|
try {
|
|
c = *(volatile CHAR *)StartAddress;
|
|
while ( c && StartAddress != EndAddress ) {
|
|
StartAddress++;
|
|
c = *(volatile CHAR *)StartAddress;
|
|
}
|
|
}
|
|
except(EXCEPTION_EXECUTE_HANDLER) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|