blob: d473ca54d855232f2efcb2ad3acf0d265deb152c (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/*++
Copyright (c) 1990-1993 Microsoft Corporation
Module Name:
probe.c
Abstract:
This module implements the probe for write function.
Author:
David N. Cutler (davec) 19-Jan-1990
Environment:
Any mode.
Revision History:
--*/
#include "exp.h"
#if defined(ALLOC_PRAGMA)
#pragma alloc_text(PAGE, ProbeForWrite)
#endif
VOID
ProbeForWrite (
IN PVOID Address,
IN ULONG Length,
IN ULONG Alignment
)
/*++
Routine Description:
This function probes a structure for write accessibility and ensures
correct alignment of the structure. If the structure is not accessible
or has incorrect alignment, then an exception is raised.
Arguments:
Address - Supplies a pointer to the structure to be probed.
Length - Supplies the length of the structure.
Alignment - Supplies the required alignment of the structure expressed
as the number of bytes in the primitive datatype (e.g., 1 for char,
2 for short, 4 for long, and 8 for quad).
Return Value:
None.
--*/
{
ULONG EndAddress;
ULONG StartAddress;
//
// If the structure has zero length, then do not probe the structure for
// write accessibility or alignment.
//
if (Length != 0) {
//
// If the structure is not properly aligned, then raise a data
// misalignment exception.
//
ASSERT((Alignment == 1) || (Alignment == 2) ||
(Alignment == 4) || (Alignment == 8));
StartAddress = (ULONG)Address;
if ((StartAddress & (Alignment - 1)) == 0) {
//
// Compute the ending address of the structure and probe for
// write accessibility.
//
EndAddress = StartAddress + Length - 1;
if ((StartAddress <= EndAddress) &
(EndAddress < MM_USER_PROBE_ADDRESS)) {
//
// N.B. Only the contents of the buffer may be probed.
// Therefore the starting byte is probed for the
// first page, and then the first byte in the page
// for each succeeding page.
//
EndAddress = (EndAddress & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
do {
*(volatile CHAR *)StartAddress = *(volatile CHAR *)StartAddress;
StartAddress = (StartAddress & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
} while (StartAddress != EndAddress);
return;
} else {
ExRaiseAccessViolation();
}
} else {
ExRaiseDatatypeMisalignment();
}
}
return;
}
|