ReactOS 0.4.17-dev-650-gd0e71de
RtlMemIoResource.c File Reference
#include "precomp.h"
#include <limits.h>
Include dependency graph for RtlMemIoResource.c:

Go to the source code of this file.

Functions

static ULONGLONG (NTAPI *pRtlCmDecodeMemIoResource)(_In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
 
static NTSTATUS (NTAPI *pRtlCmEncodeMemIoResource)(_In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
 
static void Test_CmEncode (void)
 
static void Test_CmDecode (void)
 
static void Test_IoEncode (void)
 
static void Test_IoDecode (void)
 
static void Test_FindClosest (void)
 
 START_TEST (RtlMemIoResource)
 

Variables

static _Out_opt_ PULONGLONG Start
 
static _In_ UCHAR Type
 
static _In_ UCHAR _In_ ULONGLONG Length
 
static _Out_ PULONGLONG TargetLength
 
static _Out_opt_ PULONGLONG Alignment
 
static _Out_opt_ PULONGLONG _Out_opt_ PULONGLONG MinimumAddress
 
static _Out_opt_ PULONGLONG _Out_opt_ PULONGLONG _Out_opt_ PULONGLONG MaximumAddress
 

Function Documentation

◆ NTSTATUS()

static NTSTATUS ( NTAPI pRtlCmEncodeMemIoResource)
static

◆ START_TEST()

START_TEST ( RtlMemIoResource  )

Definition at line 479 of file RtlMemIoResource.c.

480{
481 HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
482
483 pRtlCmDecodeMemIoResource = (PVOID)GetProcAddress(hNtdll, "RtlCmDecodeMemIoResource");
484 pRtlCmEncodeMemIoResource = (PVOID)GetProcAddress(hNtdll, "RtlCmEncodeMemIoResource");
485 pRtlFindClosestEncodableLength = (PVOID)GetProcAddress(hNtdll, "RtlFindClosestEncodableLength");
486 pRtlIoDecodeMemIoResource = (PVOID)GetProcAddress(hNtdll, "RtlIoDecodeMemIoResource");
487 pRtlIoEncodeMemIoResource = (PVOID)GetProcAddress(hNtdll, "RtlIoEncodeMemIoResource");
488
489 if (!pRtlCmDecodeMemIoResource || !pRtlCmEncodeMemIoResource ||
490 !pRtlFindClosestEncodableLength ||
491 !pRtlIoDecodeMemIoResource || !pRtlIoEncodeMemIoResource)
492 {
493 skip("Rtl*MemIoResource API not available (NT 6.0+ only)\n");
494 return;
495 }
496
502}
static void Test_IoEncode(void)
static void Test_FindClosest(void)
static void Test_CmDecode(void)
static void Test_IoDecode(void)
static void Test_CmEncode(void)
#define skip(...)
Definition: atltest.h:64
#define GetProcAddress(x, y)
Definition: compat.h:753
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
#define L(x)
Definition: resources.c:13
static HMODULE hNtdll
Definition: integrity.c:31
void * PVOID
Definition: typedefs.h:50

◆ Test_CmDecode()

static void Test_CmDecode ( void  )
static

Definition at line 154 of file RtlMemIoResource.c.

155{
156 static const struct
157 {
159 USHORT ExpectedFlags;
160 } RoundTrips[] =
161 {
162 { 0x1000, 0 },
163 { MAXULONG, 0 },
164 { 0x100000000ULL, CM_RESOURCE_MEMORY_LARGE_40 },
165 { 0xFFFFFFFF00ULL, CM_RESOURCE_MEMORY_LARGE_40 },
166 { 0x10000000000ULL, CM_RESOURCE_MEMORY_LARGE_48 },
167 { 0xFFFFFFFF0000ULL, CM_RESOURCE_MEMORY_LARGE_48 },
168 { 0x1000000000000ULL, CM_RESOURCE_MEMORY_LARGE_64 },
169 { 0xFFFFFFFF00000000ULL, CM_RESOURCE_MEMORY_LARGE_64 },
170 };
174 ULONG i;
175
176 /* Plain port descriptor decodes verbatim */
177 RtlZeroMemory(&Desc, sizeof(Desc));
179 Desc.u.Port.Start.QuadPart = 0x1122334455667788ULL;
180 Desc.u.Port.Length = 0x1234;
181 Start = 0;
182 Length = pRtlCmDecodeMemIoResource(&Desc, &Start);
183 ok_eq_hex64(Length, 0x1234);
184 ok_eq_hex64(Start, 0x1122334455667788ULL);
185
186 /* Start is optional */
187 Length = pRtlCmDecodeMemIoResource(&Desc, NULL);
188 ok_eq_hex64(Length, 0x1234);
189
190 /* Large flags are ignored for plain port/memory types */
192 Length = pRtlCmDecodeMemIoResource(&Desc, NULL);
193 ok_eq_hex64(Length, 0x1234);
194
195 /* Hand-built large forms decode to the shifted length */
196 RtlZeroMemory(&Desc, sizeof(Desc));
198 Desc.u.Memory.Length = 0x01000000;
200 ok_eq_hex64(pRtlCmDecodeMemIoResource(&Desc, NULL), 0x100000000ULL);
202 ok_eq_hex64(pRtlCmDecodeMemIoResource(&Desc, NULL), 0x10000000000ULL);
204 ok_eq_hex64(pRtlCmDecodeMemIoResource(&Desc, NULL), 0x100000000000000ULL);
205
206 /* A large type without any large flag decodes to zero, Start still returned */
207 Desc.Flags = 0;
208 Desc.u.Memory.Start.QuadPart = 0xABCD;
209 Start = 0;
210 ok_eq_hex64(pRtlCmDecodeMemIoResource(&Desc, &Start), 0);
211 ok_eq_hex64(Start, 0xABCD);
212
213 /* Encode/decode round-trips across all tiers */
214 for (i = 0; i < ARRAYSIZE(RoundTrips); i++)
215 {
216 RtlZeroMemory(&Desc, sizeof(Desc));
217 Status = pRtlCmEncodeMemIoResource(&Desc,
219 RoundTrips[i].Length,
220 0x40000000ULL + i);
221 ok(Status == STATUS_SUCCESS, "[%lu] encode failed: 0x%lx\n", i, Status);
222 ok(Desc.Flags == RoundTrips[i].ExpectedFlags,
223 "[%lu] Flags = 0x%x, expected 0x%x\n",
224 i, Desc.Flags, RoundTrips[i].ExpectedFlags);
225 Start = 0;
226 Length = pRtlCmDecodeMemIoResource(&Desc, &Start);
227 ok(Length == RoundTrips[i].Length,
228 "[%lu] Length = 0x%I64x, expected 0x%I64x\n",
229 i, Length, RoundTrips[i].Length);
230 ok(Start == 0x40000000ULL + i,
231 "[%lu] Start = 0x%I64x\n", i, Start);
232 }
233}
static _Out_opt_ PULONGLONG Start
static _In_ UCHAR _In_ ULONGLONG Length
#define ok_eq_hex64(value, expected)
Definition: apitest.h:146
#define ok(value,...)
Definition: atltest.h:57
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
Status
Definition: gdiplustypes.h:24
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define CM_RESOURCE_MEMORY_LARGE_40
Definition: cmtypes.h:134
#define CM_RESOURCE_MEMORY_LARGE_64
Definition: cmtypes.h:136
#define CM_RESOURCE_MEMORY_LARGE_48
Definition: cmtypes.h:135
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short USHORT
Definition: pedump.c:61
#define CmResourceTypeMemory
Definition: restypes.h:106
#define CmResourceTypePort
Definition: restypes.h:104
#define STATUS_SUCCESS
Definition: shellext.h:65
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@389 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@389::@391 Port
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@389::@394 Memory
#define MAXULONG
Definition: typedefs.h:251
uint64_t ULONGLONG
Definition: typedefs.h:67
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
#define CmResourceTypeMemoryLarge
Definition: cmtypes.h:231

Referenced by START_TEST().

◆ Test_CmEncode()

static void Test_CmEncode ( void  )
static

Definition at line 44 of file RtlMemIoResource.c.

45{
48
49 /* Unsupported types must fail without touching the descriptor */
50 RtlFillMemory(&Desc, sizeof(Desc), 0x55);
51 Saved = Desc;
52 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeNull, 0x1000, 0);
54 ok(!memcmp(&Desc, &Saved, sizeof(Desc)), "Descriptor modified on failure\n");
55 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeInterrupt, 0x1000, 0);
57 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeDma, 0x1000, 0);
59 ok(!memcmp(&Desc, &Saved, sizeof(Desc)), "Descriptor modified on failure\n");
60
61 /* Basic port descriptor */
62 RtlFillMemory(&Desc, sizeof(Desc), 0x55);
63 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypePort, 0x100, 0x3F8);
66 ok_eq_ulong(Desc.u.Port.Length, 0x100UL);
67 ok_eq_hex64(Desc.u.Port.Start.QuadPart, 0x3F8);
68 /* The port path does not clean stale large flags */
69 ok_eq_hex(Desc.Flags, 0x5555);
70
71 /* A port length cannot exceed 32 bits, and the failure leaves no writes */
72 RtlFillMemory(&Desc, sizeof(Desc), 0x55);
73 Saved = Desc;
74 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypePort, 0x100000000ULL, 0);
76 ok(!memcmp(&Desc, &Saved, sizeof(Desc)), "Descriptor modified on failure\n");
77
78 /* Small memory length: plain descriptor, stale large flags are cleared */
79 RtlZeroMemory(&Desc, sizeof(Desc));
81 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemory, 0x1000, 0xFFFFFFFFFF000000ULL);
84 ok_eq_ulong(Desc.u.Memory.Length, 0x1000UL);
85 ok_eq_hex64(Desc.u.Memory.Start.QuadPart, 0xFFFFFFFFFF000000ULL);
87
88 /* Asking for MemoryLarge with a small length demotes to plain Memory */
89 RtlZeroMemory(&Desc, sizeof(Desc));
90 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemoryLarge, MAXULONG, 0);
93 ok_eq_ulong(Desc.u.Memory.Length, MAXULONG);
94
95 /* Asking for plain Memory with a big length promotes to MemoryLarge (40-bit) */
96 RtlZeroMemory(&Desc, sizeof(Desc));
97 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemory, 0x100000000ULL, 0x8000000000ULL);
101 ok_eq_ulong(Desc.u.Memory.Length, 0x01000000UL);
102 ok_eq_hex64(Desc.u.Memory.Start.QuadPart, 0x8000000000ULL);
103
104 /* 40-bit tier upper bound */
105 RtlZeroMemory(&Desc, sizeof(Desc));
106 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemoryLarge, CM_RESOURCE_MEMORY_LARGE_40_MAXLEN, 0);
109 ok_eq_ulong(Desc.u.Memory.Length, MAXULONG);
110
111 /* Low 8 bits set in the 40-bit tier: not encodable */
112 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemory, 0x100000080ULL, 0);
114
115 /* 48-bit tier */
116 RtlZeroMemory(&Desc, sizeof(Desc));
117 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemory, 0x10000000000ULL, 0);
121 ok_eq_ulong(Desc.u.Memory.Length, 0x01000000UL);
122
123 /*
124 * The tier is picked by magnitude alone: a 256-byte-aligned length in the
125 * 48-bit tier still fails because it is not 64K-aligned
126 */
127 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemory, 0x10000000100ULL, 0);
129
130 /* 64-bit tier and its upper bound */
131 RtlZeroMemory(&Desc, sizeof(Desc));
132 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemory, 0x1000000000000ULL, 0);
135 ok_eq_ulong(Desc.u.Memory.Length, 0x10000UL);
136
137 RtlZeroMemory(&Desc, sizeof(Desc));
138 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemory, CM_RESOURCE_MEMORY_LARGE_64_MAXLEN, 0);
141 ok_eq_ulong(Desc.u.Memory.Length, MAXULONG);
142
143 /* Low 32 bits set in the 64-bit tier, and beyond-the-max lengths */
144 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemory, 0x100000000000100ULL, 0);
146 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemory, CM_RESOURCE_MEMORY_LARGE_64_MAXLEN + 1, 0);
148 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemory, ULLONG_MAX, 0);
150}
#define ok_eq_hex(value, expected)
Definition: apitest.h:134
#define ok_eq_ulong(value, expected)
Definition: apitest.h:120
#define ok_eq_uint(value, expected)
Definition: apitest.h:118
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
#define ULLONG_MAX
Definition: limits.h:35
#define CM_RESOURCE_MEMORY_READ_ONLY
Definition: cmtypes.h:122
#define CM_RESOURCE_MEMORY_LARGE_40_MAXLEN
Definition: cmtypes.h:138
#define CM_RESOURCE_MEMORY_LARGE_64_MAXLEN
Definition: cmtypes.h:140
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:603
#define CmResourceTypeNull
Definition: restypes.h:103
#define CmResourceTypeDma
Definition: restypes.h:107
#define CmResourceTypeInterrupt
Definition: restypes.h:105
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by START_TEST().

◆ Test_FindClosest()

static void Test_FindClosest ( void  )
static

Definition at line 424 of file RtlMemIoResource.c.

425{
426 static const struct
427 {
430 } Cases[] =
431 {
432 /* 32-bit values are always exact */
433 { 0, 0 },
434 { 0x1234, 0x1234 },
435 { MAXULONG, MAXULONG },
436 /* 40-bit tier: rounded up to 256 bytes */
437 { 0x100000000ULL, 0x100000000ULL },
438 { 0x100000001ULL, 0x100000100ULL },
439 { 0xFFFFFFFF00ULL, 0xFFFFFFFF00ULL },
440 /* just past the 40-bit tier: 64K granularity now */
441 { 0xFFFFFFFF01ULL, 0x10000000000ULL },
442 { 0x10000000001ULL, 0x10000010000ULL },
443 { 0xFFFFFFFF0000ULL, 0xFFFFFFFF0000ULL },
444 /* just past the 48-bit tier: 4G granularity */
445 { 0xFFFFFFFF0001ULL, 0x1000000000000ULL },
446 { 0x1000000000000ULL, 0x1000000000000ULL },
447 { 0x1000000000001ULL, 0x1000100000000ULL },
448 { 0xFFFFFFFF00000000ULL, 0xFFFFFFFF00000000ULL },
449 };
453 ULONG i;
454
455 for (i = 0; i < ARRAYSIZE(Cases); i++)
456 {
458 Status = pRtlFindClosestEncodableLength(Cases[i].Source, &Target);
459 ok(Status == STATUS_SUCCESS, "[%lu] failed: 0x%lx\n", i, Status);
460 ok(Target == Cases[i].Expected,
461 "[%lu] Target = 0x%I64x, expected 0x%I64x\n",
462 i, Target, Cases[i].Expected);
463
464 /* The returned length must itself be encodable */
465 RtlZeroMemory(&Desc, sizeof(Desc));
466 Status = pRtlCmEncodeMemIoResource(&Desc, CmResourceTypeMemory, Target, 0);
467 ok(Status == STATUS_SUCCESS, "[%lu] closest length not encodable: 0x%lx\n", i, Status);
468 }
469
470 /* Beyond the 64-bit tier there is nothing to round to */
472 Status = pRtlFindClosestEncodableLength(CM_RESOURCE_MEMORY_LARGE_64_MAXLEN + 1, &Target);
475 Status = pRtlFindClosestEncodableLength(ULLONG_MAX, &Target);
477}
BOOLEAN Expected
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306

Referenced by START_TEST().

◆ Test_IoDecode()

static void Test_IoDecode ( void  )
static

Definition at line 353 of file RtlMemIoResource.c.

354{
356 ULONGLONG Length, Alignment, Minimum, Maximum;
358
359 /* Plain memory requirement */
360 RtlZeroMemory(&Desc, sizeof(Desc));
362 Desc.u.Memory.Length = 0x2000;
363 Desc.u.Memory.Alignment = 0x1000;
364 Desc.u.Memory.MinimumAddress.QuadPart = 0x100000;
365 Desc.u.Memory.MaximumAddress.QuadPart = 0xFFFFFFFFULL;
366 Alignment = Minimum = Maximum = 0;
367 Length = pRtlIoDecodeMemIoResource(&Desc, &Alignment, &Minimum, &Maximum);
368 ok_eq_hex64(Length, 0x2000);
369 ok_eq_hex64(Alignment, 0x1000);
370 ok_eq_hex64(Minimum, 0x100000);
371 ok_eq_hex64(Maximum, 0xFFFFFFFFULL);
372
373 Length = pRtlIoDecodeMemIoResource(&Desc, NULL, NULL, NULL);
374 ok_eq_hex64(Length, 0x2000);
375
376 /* Length and alignment both scale */
377 RtlZeroMemory(&Desc, sizeof(Desc));
380 Desc.u.Memory.Length = 0x01000000;
381 Desc.u.Memory.Alignment = 0x01000000;
382 Alignment = 0;
383 Length = pRtlIoDecodeMemIoResource(&Desc, &Alignment, NULL, NULL);
384 ok_eq_hex64(Length, 0x100000000ULL);
385 ok_eq_hex64(Alignment, 0x100000000ULL);
386
388 Length = pRtlIoDecodeMemIoResource(&Desc, &Alignment, NULL, NULL);
389 ok_eq_hex64(Length, 0x10000000000ULL);
390 ok_eq_hex64(Alignment, 0x10000000000ULL);
391
393 Length = pRtlIoDecodeMemIoResource(&Desc, &Alignment, NULL, NULL);
394 ok_eq_hex64(Length, 0x100000000000000ULL);
395 ok_eq_hex64(Alignment, 0x100000000000000ULL);
396
397 /* A large type without large flags decodes to zero, bounds still returned */
398 Desc.Flags = 0;
399 Desc.u.Memory.MinimumAddress.QuadPart = 0x1234;
400 Desc.u.Memory.MaximumAddress.QuadPart = 0x5678;
401 Alignment = Minimum = Maximum = ULLONG_MAX;
402 Length = pRtlIoDecodeMemIoResource(&Desc, &Alignment, &Minimum, &Maximum);
405 ok_eq_hex64(Minimum, 0x1234);
406 ok_eq_hex64(Maximum, 0x5678);
407
408 /* Encode/decode round-trip: the rounded-up alignment is what comes back */
409 RtlZeroMemory(&Desc, sizeof(Desc));
410 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeMemory,
411 0x10000000000ULL, 0x1000,
412 0x10000, 0xFFFFFFFFFFFFULL);
414 Alignment = Minimum = Maximum = 0;
415 Length = pRtlIoDecodeMemIoResource(&Desc, &Alignment, &Minimum, &Maximum);
416 ok_eq_hex64(Length, 0x10000000000ULL);
417 ok_eq_hex64(Alignment, 0x10000); /* 0x1000 rounded up to the 64K granularity */
418 ok_eq_hex64(Minimum, 0x10000);
419 ok_eq_hex64(Maximum, 0xFFFFFFFFFFFFULL);
420}
static _Out_opt_ PULONGLONG Alignment
struct _IO_RESOURCE_DESCRIPTOR::@2271::@2273 Memory
union _IO_RESOURCE_DESCRIPTOR::@2271 u

Referenced by START_TEST().

◆ Test_IoEncode()

static void Test_IoEncode ( void  )
static

Definition at line 237 of file RtlMemIoResource.c.

238{
239 IO_RESOURCE_DESCRIPTOR Desc, Saved;
241
242 /* Unsupported types fail without touching the descriptor */
243 RtlFillMemory(&Desc, sizeof(Desc), 0x55);
244 Saved = Desc;
245 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeInterrupt, 0x1000, 4, 0, 0xFFFF);
247 ok(!memcmp(&Desc, &Saved, sizeof(Desc)), "Descriptor modified on failure\n");
248
249 /* Basic port requirement */
250 RtlFillMemory(&Desc, sizeof(Desc), 0x55);
251 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypePort, 0x100, 4, 0x1000, 0xFFFF);
254 ok_eq_ulong(Desc.u.Port.Length, 0x100UL);
255 ok_eq_ulong(Desc.u.Port.Alignment, 4UL);
256 ok_eq_hex64(Desc.u.Port.MinimumAddress.QuadPart, 0x1000);
257 ok_eq_hex64(Desc.u.Port.MaximumAddress.QuadPart, 0xFFFF);
258
259 /* Port length/alignment above 32 bits are rejected, no writes */
260 RtlFillMemory(&Desc, sizeof(Desc), 0x55);
261 Saved = Desc;
262 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypePort, 0x100000000ULL, 4, 0, 0xFFFF);
264 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypePort, 0x100, 0x100000000ULL, 0, 0xFFFF);
266 ok(!memcmp(&Desc, &Saved, sizeof(Desc)), "Descriptor modified on failure\n");
267
268 /* Small memory requirement stays plain and clears stale large flags */
269 RtlZeroMemory(&Desc, sizeof(Desc));
271 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeMemory, 0x1000, 0x1000, 0, 0xFFFFFFFFULL);
275 ok_eq_ulong(Desc.u.Memory.Length, 0x1000UL);
276 ok_eq_ulong(Desc.u.Memory.Alignment, 0x1000UL);
277 ok_eq_hex64(Desc.u.Memory.MinimumAddress.QuadPart, 0);
278 ok_eq_hex64(Desc.u.Memory.MaximumAddress.QuadPart, 0xFFFFFFFFULL);
279
280 /* Large length: a small alignment is scaled up to the tier granularity */
281 RtlZeroMemory(&Desc, sizeof(Desc));
282 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeMemory,
283 0x100000000ULL, 1,
284 0, 0xFFFFFFFFFFULL);
288 ok_eq_ulong(Desc.u.Memory.Length, 0x01000000UL);
289 ok_eq_ulong(Desc.u.Memory.Alignment, 1UL); /* i.e. 0x100 bytes */
290 ok_eq_hex64(Desc.u.Memory.MaximumAddress.QuadPart, 0xFFFFFFFFFFULL);
291
292 /* Zero alignment encodes as zero */
293 RtlZeroMemory(&Desc, sizeof(Desc));
294 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeMemory, 0x100000000ULL, 0, 0, 0);
296 ok_eq_ulong(Desc.u.Memory.Alignment, 0UL);
297
298 /* A non-power-of-two alignment is doubled until it fits the granularity */
299 RtlZeroMemory(&Desc, sizeof(Desc));
300 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeMemory, 0x100000000ULL, 0x81, 0, 0);
302 ok_eq_ulong(Desc.u.Memory.Alignment, 0x81UL); /* 0x81 << 8 == 0x8100 bytes */
303
304 /*
305 * A small length with a >4GB alignment still selects the large form
306 * (the plain path needs both to fit in 32 bits)
307 */
308 RtlZeroMemory(&Desc, sizeof(Desc));
309 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeMemory,
310 0x1000, 0x100000000ULL, 0, 0);
314 ok_eq_ulong(Desc.u.Memory.Length, 0x10UL);
315 ok_eq_ulong(Desc.u.Memory.Alignment, 0x01000000UL);
316
317 /* Length not representable at the tier granularity */
318 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeMemory, 0x100000080ULL, 1, 0, 0);
320 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeMemory, 0x10000000100ULL, 1, 0, 0);
322
323 /* Alignment above the tier picked by the length */
324 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeMemory,
325 0x100000000ULL, 0x10000000000ULL, 0, 0);
327
328 /* Alignment whose scaling overflows 64 bits */
329 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeMemory,
330 0x1000000000000ULL, 0x8000000000000001ULL, 0, 0);
332
333 /* 64-bit tier */
334 RtlZeroMemory(&Desc, sizeof(Desc));
335 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeMemory,
336 0x1000000000000ULL, 0x100000000ULL,
337 0x100000000ULL, 0xFFFFFFFFFFFFFFFFULL);
340 ok_eq_ulong(Desc.u.Memory.Length, 0x10000UL);
341 ok_eq_ulong(Desc.u.Memory.Alignment, 1UL);
342 ok_eq_hex64(Desc.u.Memory.MinimumAddress.QuadPart, 0x100000000ULL);
343 ok_eq_hex64(Desc.u.Memory.MaximumAddress.QuadPart, 0xFFFFFFFFFFFFFFFFULL);
344
345 /* Length beyond every tier */
346 Status = pRtlIoEncodeMemIoResource(&Desc, CmResourceTypeMemory,
347 ULLONG_MAX, 1, 0, 0);
349}
#define CM_RESOURCE_MEMORY_PREFETCHABLE
Definition: cmtypes.h:125
struct _IO_RESOURCE_DESCRIPTOR::@2271::@2272 Port
#define UL
Definition: tui.h:164

Referenced by START_TEST().

◆ ULONGLONG()

static ULONGLONG ( NTAPI pRtlCmDecodeMemIoResource)
static

Variable Documentation

◆ Alignment

Definition at line 30 of file RtlMemIoResource.c.

Referenced by Test_IoDecode().

◆ Length

Definition at line 21 of file RtlMemIoResource.c.

Referenced by Test_CmDecode(), and Test_IoDecode().

◆ MaximumAddress

◆ MinimumAddress

Definition at line 31 of file RtlMemIoResource.c.

Referenced by RtlIoDecodeMemIoResource(), and RtlIoEncodeMemIoResource().

◆ Start

Definition at line 16 of file RtlMemIoResource.c.

Referenced by AcpiPsGetNextNamepath(), AcpiPsGetNextNamestring(), AcpiPsGetNextPackageEnd(), FxResourceCollection::AddAt(), ArbiterLibAddOrdering(), ArbpAddOrderingCallback(), AtaTrimIdString(), BSTR_UserSize(), CcpDereferenceCache(), CcpMarkForExclusive(), CcpReferenceCache(), CcpReferenceCacheExclusive(), CLEANLOCALSTORAGE_UserSize(), ConioComputeUpdateRect(), ConvertConfigToVA(), FxCmResList::CreateWdmList(), FxIoResReqList::CreateWdmList(), DECLARE_INTERFACE_(), EnumNameServers(), Ext2AddBlockExtent(), Ext2BuildExtents(), Ext2ExpandBlock(), Ext2ExpandExtent(), Ext2ExpandFile(), Ext2ExpandIndirect(), Ext2GetBlock(), Ext2InitializeZone(), Ext2LookupBlockExtent(), Ext2LookupFile(), Ext2RemoveBlockExtent(), Ext2TruncateBlock(), Ext2ZeroData(), FatIsIoRangeValid(), FileAsyncReader_Request(), FindVerbInDefaultVerbList(), ForDir(), ForF(), ForLoop(), FsRtlTest_FillBuffer(), FsVolCommitOpsQueue(), FxUsbFindDescriptorType(), FxUsbValidateDescriptorType(), GetAdapterResources(), FxCmResList::GetResourceLength(), GuiPaintTextModeBuffer(), HTMLTxtRange_collapse(), InitRomRange(), IntDrawArc(), interface_user_size(), IntExtTextOutW(), IntFillArc(), IntSetPaletteEntries(), IntValidateParents(), IopArbBusNumberPackResource(), IopArbBusNumberUnpackResource(), IopArbDmaPackResource(), IopArbDmaUnpackResource(), IopArbIrqPackResource(), IopArbIrqUnpackResource(), IopArbMemPackResource(), IopArbMemUnpackResource(), IopFindBusNumberResource(), IopFindMemoryResource(), IopFindPortResource(), IopPortMemPackResource(), IopPortMemUnpackResource(), Is1On(), Is24On(), KdbpGetNextBreakPointNr(), CKsInterfaceHandler::KsCompleteIo(), LdrpNameToOrdinal(), CDowloadingAppsListView::LoadList(), main(), Open(), PALOBJ_cGetColors(), PciBuildDefaultExclusionLists(), Protocol_Start(), ProtocolEmul_Continue(), ProtocolEmul_Start(), ReadVolumeLabel(), RtlAddRange(), RtlCmDecodeMemIoResource(), RtlCmEncodeMemIoResource(), RtlDeleteRange(), RtlFindRange(), RtlIsDosDeviceName_Ustr(), RtlIsRangeAvailable(), RtlpConflictsOnAdd(), RtlpDphIsPageHeapBlock(), RtlpWindowIsAvailable(), RtlSeekMemoryStream(), ScControl(), Set1(), CRichEdit::SetRangeFormatting(), SHELL32_EnumDefaultVerbList(), _MdTimer::StartWithReturn(), StringHashTableInit(), SubstituteVar(), test_binding(), test_BindToObject(), test_BindToStorage(), Test_CmDecode(), test_CreateBinding(), test_download(), test_ReportResult(), test_submit(), Test_SyscallPerformance(), test_URLDownloadToFile(), TestAddConflict(), TestFindRange(), TestGetLastRange(), TestIsAvailable(), TestSharedFlag(), TestSharedNullCallback(), TestStartEqualsEnd(), UmaMgrInitialize(), USBPORT_SynchronizeControllersStart(), VARIANT_UserSize(), VGADDI_InitializeOffScreenMem(), and wire_extra_user_size().

◆ TargetLength

◆ Type

Definition at line 20 of file RtlMemIoResource.c.