virtual.c 18.9 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2 3 4
/*
 * Win32 virtual memory functions
 *
 * Copyright 1997 Alexandre Julliard
5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Alexandre Julliard's avatar
Alexandre Julliard committed
19 20
 */

21
#include "config.h"
22
#include "wine/port.h"
23

Alexandre Julliard's avatar
Alexandre Julliard committed
24
#include <fcntl.h>
25
#include <stdarg.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
26 27 28
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
29 30
#ifdef HAVE_UNISTD_H
# include <unistd.h>
31
#endif
32

33
#include "ntstatus.h"
34
#define WIN32_NO_STATUS
35
#define NONAMELESSUNION
36
#include "windef.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
37
#include "winbase.h"
38
#include "winnls.h"
39
#include "winternl.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
40
#include "winerror.h"
41
#include "psapi.h"
42
#include "wine/exception.h"
43
#include "wine/debug.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
44

45 46
#include "kernel_private.h"

47
WINE_DECLARE_DEBUG_CHANNEL(seh);
48
WINE_DECLARE_DEBUG_CHANNEL(file);
Alexandre Julliard's avatar
Alexandre Julliard committed
49

Alexandre Julliard's avatar
Alexandre Julliard committed
50 51

/***********************************************************************
52
 *             VirtualAlloc   (KERNEL32.@)
53 54 55 56 57 58 59 60
 *
 * Reserves or commits a region of pages in virtual address space.
 *
 * PARAMS
 *  addr    [I] Address of region to reserve or commit.
 *  size    [I] Size of region.
 *  type    [I] Type of allocation.
 *  protect [I] Type of access protection.
Alexandre Julliard's avatar
Alexandre Julliard committed
61 62
 *
 * RETURNS
63 64
 *	Success: Base address of allocated region of pages.
 *	Failure: NULL.
Alexandre Julliard's avatar
Alexandre Julliard committed
65
 */
66
LPVOID WINAPI DECLSPEC_HOTPATCH VirtualAlloc( void *addr, SIZE_T size, DWORD type, DWORD protect )
67
{
68
    return VirtualAllocEx( GetCurrentProcess(), addr, size, type, protect );
Alexandre Julliard's avatar
Alexandre Julliard committed
69 70 71 72
}


/***********************************************************************
73
 *             VirtualAllocEx   (KERNEL32.@)
Alexandre Julliard's avatar
Alexandre Julliard committed
74
 *
75
 * Seems to be just as VirtualAlloc, but with process handle.
76
 *
77 78 79 80 81 82 83 84
 * PARAMS
 *  hProcess [I] Handle to process to do mem operation.
 *  addr     [I] Address of region to reserve or commit.
 *  size     [I] Size of region.
 *  type     [I] Type of allocation.
 *  protect  [I] Type of access protection.
 *
 *
85
 * RETURNS
86 87
 *	Success: Base address of allocated region of pages.
 *	Failure: NULL.
Alexandre Julliard's avatar
Alexandre Julliard committed
88
 */
89 90
LPVOID WINAPI VirtualAllocEx( HANDLE hProcess, LPVOID addr, SIZE_T size,
    DWORD type, DWORD protect )
Alexandre Julliard's avatar
Alexandre Julliard committed
91
{
92
    LPVOID ret = addr;
93
    NTSTATUS status;
Alexandre Julliard's avatar
Alexandre Julliard committed
94

95
    if ((status = NtAllocateVirtualMemory( hProcess, &ret, 0, &size, type, protect )))
Alexandre Julliard's avatar
Alexandre Julliard committed
96
    {
97 98
        SetLastError( RtlNtStatusToDosError(status) );
        ret = NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
99
    }
100
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
101 102 103 104
}


/***********************************************************************
105
 *             VirtualFree   (KERNEL32.@)
106 107 108 109 110 111 112
 *
 * Releases or decommits a region of pages in virtual address space.
 *
 * PARAMS
 *  addr [I] Address of region of committed pages.
 *  size [I] Size of region.
 *  type [I] Type of operation.
Alexandre Julliard's avatar
Alexandre Julliard committed
113 114
 *
 * RETURNS
115 116
 *	Success: TRUE.
 *	Failure: FALSE.
Alexandre Julliard's avatar
Alexandre Julliard committed
117
 */
118 119
BOOL WINAPI VirtualFree( LPVOID addr, SIZE_T size, DWORD type )
{
120
    return VirtualFreeEx( GetCurrentProcess(), addr, size, type );
Alexandre Julliard's avatar
Alexandre Julliard committed
121 122 123 124
}


/***********************************************************************
125
 *             VirtualFreeEx   (KERNEL32.@)
126 127 128 129 130 131 132 133
 *
 * Releases or decommits a region of pages in virtual address space.
 *
 * PARAMS
 *  process [I] Handle to process.
 *  addr    [I] Address of region to free.
 *  size    [I] Size of region.
 *  type    [I] Type of operation.
Alexandre Julliard's avatar
Alexandre Julliard committed
134 135
 *
 * RETURNS
136 137
 *	Success: TRUE.
 *	Failure: FALSE.
Alexandre Julliard's avatar
Alexandre Julliard committed
138
 */
139
BOOL WINAPI VirtualFreeEx( HANDLE process, LPVOID addr, SIZE_T size, DWORD type )
140 141 142 143
{
    NTSTATUS status = NtFreeVirtualMemory( process, &addr, &size, type );
    if (status) SetLastError( RtlNtStatusToDosError(status) );
    return !status;
Alexandre Julliard's avatar
Alexandre Julliard committed
144 145 146 147
}


/***********************************************************************
148
 *             VirtualLock   (KERNEL32.@)
Alexandre Julliard's avatar
Alexandre Julliard committed
149
 *
150 151 152 153 154
 * Locks the specified region of virtual address space.
 *
 * PARAMS
 *  addr [I] Address of first byte of range to lock.
 *  size [I] Number of bytes in range to lock.
Alexandre Julliard's avatar
Alexandre Julliard committed
155 156
 *
 * RETURNS
157 158 159 160 161 162
 *	Success: TRUE.
 *	Failure: FALSE.
 *
 * NOTES
 *	Always returns TRUE.
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
163
 */
164
BOOL WINAPI VirtualLock( LPVOID addr, SIZE_T size )
165
{
166 167 168
    NTSTATUS status = NtLockVirtualMemory( GetCurrentProcess(), &addr, &size, 1 );
    if (status) SetLastError( RtlNtStatusToDosError(status) );
    return !status;
169 170 171
}


172
/***********************************************************************
173
 *             VirtualUnlock   (KERNEL32.@)
174
 *
175 176 177 178 179
 * Unlocks a range of pages in the virtual address space.
 *
 * PARAMS
 *  addr [I] Address of first byte of range.
 *  size [I] Number of bytes in range.
180
 *
181
 * RETURNS
182 183 184 185 186 187
 *	Success: TRUE.
 *	Failure: FALSE.
 *
 * NOTES
 *	Always returns TRUE.
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
188
 */
189
BOOL WINAPI VirtualUnlock( LPVOID addr, SIZE_T size )
Alexandre Julliard's avatar
Alexandre Julliard committed
190
{
191 192 193
    NTSTATUS status = NtUnlockVirtualMemory( GetCurrentProcess(), &addr, &size, 1 );
    if (status) SetLastError( RtlNtStatusToDosError(status) );
    return !status;
Alexandre Julliard's avatar
Alexandre Julliard committed
194 195 196
}


197
/***********************************************************************
198
 *             VirtualProtect   (KERNEL32.@)
199 200 201 202 203 204 205 206
 *
 * Changes the access protection on a region of committed pages.
 *
 * PARAMS
 *  addr     [I] Address of region of committed pages.
 *  size     [I] Size of region.
 *  new_prot [I] Desired access protection.
 *  old_prot [O] Address of variable to get old protection.
Alexandre Julliard's avatar
Alexandre Julliard committed
207 208
 *
 * RETURNS
209 210
 *	Success: TRUE.
 *	Failure: FALSE.
211
 */
212 213
BOOL WINAPI VirtualProtect( LPVOID addr, SIZE_T size, DWORD new_prot, LPDWORD old_prot)
{
214
    return VirtualProtectEx( GetCurrentProcess(), addr, size, new_prot, old_prot );
Alexandre Julliard's avatar
Alexandre Julliard committed
215 216 217 218
}


/***********************************************************************
219
 *             VirtualProtectEx   (KERNEL32.@)
220
 *
221
 * Changes the access protection on a region of committed pages in the
222 223 224 225 226 227 228 229
 * virtual address space of a specified process.
 *
 * PARAMS
 *  process  [I] Handle of process.
 *  addr     [I] Address of region of committed pages.
 *  size     [I] Size of region.
 *  new_prot [I] Desired access protection.
 *  old_prot [O] Address of variable to get old protection.
Alexandre Julliard's avatar
Alexandre Julliard committed
230 231
 *
 * RETURNS
232 233
 *	Success: TRUE.
 *	Failure: FALSE.
Alexandre Julliard's avatar
Alexandre Julliard committed
234
 */
235 236
BOOL WINAPI VirtualProtectEx( HANDLE process, LPVOID addr, SIZE_T size,
    DWORD new_prot, LPDWORD old_prot )
237
{
238 239 240
    NTSTATUS status;
    DWORD prot;

241
    /* Win9x allows passing NULL as old_prot while this fails on NT */
242 243 244
    if (!old_prot && (GetVersion() & 0x80000000)) old_prot = &prot;

    status = NtProtectVirtualMemory( process, &addr, &size, new_prot, old_prot );
245 246
    if (status) SetLastError( RtlNtStatusToDosError(status) );
    return !status;
Alexandre Julliard's avatar
Alexandre Julliard committed
247 248 249 250
}


/***********************************************************************
251
 *             VirtualQuery   (KERNEL32.@)
252 253 254 255 256 257 258
 *
 * Provides info about a range of pages in virtual address space.
 *
 * PARAMS
 *  addr [I] Address of region.
 *  info [O] Address of info buffer.
 *  len  [I] Size of buffer.
Alexandre Julliard's avatar
Alexandre Julliard committed
259 260
 *
 * RETURNS
261 262
 *	Number of bytes returned in information buffer or 0 if
 *	addr >= 0xc0000000 (kernel space).
Alexandre Julliard's avatar
Alexandre Julliard committed
263
 */
264 265 266
SIZE_T WINAPI VirtualQuery( LPCVOID addr, PMEMORY_BASIC_INFORMATION info,
    SIZE_T len )
{
267
    return VirtualQueryEx( GetCurrentProcess(), addr, info, len );
Alexandre Julliard's avatar
Alexandre Julliard committed
268 269 270 271
}


/***********************************************************************
272
 *             VirtualQueryEx   (KERNEL32.@)
273
 *
274
 * Provides info about a range of pages in virtual address space of a
275 276 277 278 279 280 281
 * specified process.
 *
 * PARAMS
 *  process [I] Handle to process.
 *  addr    [I] Address of region.
 *  info    [O] Address of info buffer.
 *  len     [I] Size of buffer.
282 283
 *
 * RETURNS
284
 *	Number of bytes returned in information buffer.
Alexandre Julliard's avatar
Alexandre Julliard committed
285
 */
286 287
SIZE_T WINAPI VirtualQueryEx( HANDLE process, LPCVOID addr,
    PMEMORY_BASIC_INFORMATION info, SIZE_T len )
Alexandre Julliard's avatar
Alexandre Julliard committed
288
{
289
    SIZE_T ret;
290 291 292
    NTSTATUS status;

    if ((status = NtQueryVirtualMemory( process, addr, MemoryBasicInformation, info, len, &ret )))
Alexandre Julliard's avatar
Alexandre Julliard committed
293
    {
294 295
        SetLastError( RtlNtStatusToDosError(status) );
        ret = 0;
296 297
    }
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
298 299 300 301
}


/***********************************************************************
302
 *             MapViewOfFile   (KERNEL32.@)
303 304 305 306 307 308 309 310 311
 *
 * Maps a view of a file into the address space.
 *
 * PARAMS
 *  mapping     [I] File-mapping object to map.
 *  access      [I] Access mode.
 *  offset_high [I] High-order 32 bits of file offset.
 *  offset_low  [I] Low-order 32 bits of file offset.
 *  count       [I] Number of bytes to map.
Alexandre Julliard's avatar
Alexandre Julliard committed
312 313
 *
 * RETURNS
314 315
 *	Success: Starting address of mapped view.
 *	Failure: NULL.
Alexandre Julliard's avatar
Alexandre Julliard committed
316
 */
317
LPVOID WINAPI DECLSPEC_HOTPATCH MapViewOfFile( HANDLE mapping, DWORD access,
318 319
    DWORD offset_high, DWORD offset_low, SIZE_T count )
{
Alexandre Julliard's avatar
Alexandre Julliard committed
320 321 322 323 324 325
    return MapViewOfFileEx( mapping, access, offset_high,
                            offset_low, count, NULL );
}


/***********************************************************************
326
 *             MapViewOfFileEx   (KERNEL32.@)
327 328 329 330 331 332 333 334 335 336
 *
 * Maps a view of a file into the address space.
 *
 * PARAMS
 *  handle      [I] File-mapping object to map.
 *  access      [I] Access mode.
 *  offset_high [I] High-order 32 bits of file offset.
 *  offset_low  [I] Low-order 32 bits of file offset.
 *  count       [I] Number of bytes to map.
 *  addr        [I] Suggested starting address for mapped view.
Alexandre Julliard's avatar
Alexandre Julliard committed
337 338
 *
 * RETURNS
339 340
 *	Success: Starting address of mapped view.
 *	Failure: NULL.
Alexandre Julliard's avatar
Alexandre Julliard committed
341
 */
342 343 344
LPVOID WINAPI MapViewOfFileEx( HANDLE handle, DWORD access,
    DWORD offset_high, DWORD offset_low, SIZE_T count, LPVOID addr )
{
345 346 347
    NTSTATUS status;
    LARGE_INTEGER offset;
    ULONG protect;
348
    BOOL exec;
349

350 351
    offset.u.LowPart  = offset_low;
    offset.u.HighPart = offset_high;
352

353 354
    exec = access & FILE_MAP_EXECUTE;
    access &= ~FILE_MAP_EXECUTE;
Alexandre Julliard's avatar
Alexandre Julliard committed
355

356 357 358 359 360 361 362
    if (access == FILE_MAP_COPY)
        protect = exec ? PAGE_EXECUTE_WRITECOPY : PAGE_WRITECOPY;
    else if (access & FILE_MAP_WRITE)
        protect = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
    else if (access & FILE_MAP_READ)
        protect = exec ? PAGE_EXECUTE_READ : PAGE_READONLY;
    else protect = PAGE_NOACCESS;
363

364
    if ((status = NtMapViewOfSection( handle, GetCurrentProcess(), &addr, 0, 0, &offset,
365
                                      &count, ViewShare, 0, protect )) < 0)
366
    {
367 368
        SetLastError( RtlNtStatusToDosError(status) );
        addr = NULL;
369
    }
370 371
    return addr;
}
372

373

374 375
/***********************************************************************
 *             UnmapViewOfFile   (KERNEL32.@)
376
 *
377 378
 * Unmaps a mapped view of a file.
 *
379 380
 * PARAMS
 *  addr [I] Address where mapped view begins.
381 382
 *
 * RETURNS
383 384 385
 *	Success: TRUE.
 *	Failure: FALSE.
 *
386
 */
387
BOOL WINAPI UnmapViewOfFile( LPCVOID addr )
388
{
389 390 391 392 393 394 395 396 397 398 399 400 401
    NTSTATUS status;

    if (GetVersion() & 0x80000000)
    {
        MEMORY_BASIC_INFORMATION info;
        if (!VirtualQuery( addr, &info, sizeof(info) ) || info.AllocationBase != addr)
        {
            SetLastError( ERROR_INVALID_ADDRESS );
            return FALSE;
        }
    }

    status = NtUnmapViewOfSection( GetCurrentProcess(), (void *)addr );
402 403 404
    if (status) SetLastError( RtlNtStatusToDosError(status) );
    return !status;
}
405

Alexandre Julliard's avatar
Alexandre Julliard committed
406

407 408
/***********************************************************************
 *             FlushViewOfFile   (KERNEL32.@)
409 410 411 412 413 414
 *
 * Writes to the disk a byte range within a mapped view of a file.
 *
 * PARAMS
 *  base [I] Start address of byte range to flush.
 *  size [I] Number of bytes in range.
415 416
 *
 * RETURNS
417 418
 *	Success: TRUE.
 *	Failure: FALSE.
419
 */
420
BOOL WINAPI FlushViewOfFile( LPCVOID base, SIZE_T size )
421 422 423
{
    NTSTATUS status = NtFlushVirtualMemory( GetCurrentProcess(), &base, &size, 0 );
    if (status)
Alexandre Julliard's avatar
Alexandre Julliard committed
424
    {
425 426
        if (status == STATUS_NOT_MAPPED_DATA) status = STATUS_SUCCESS;
        else SetLastError( RtlNtStatusToDosError(status) );
Alexandre Julliard's avatar
Alexandre Julliard committed
427
    }
428 429
    return !status;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
430

431

432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
/***********************************************************************
 *             GetWriteWatch   (KERNEL32.@)
 */
UINT WINAPI GetWriteWatch( DWORD flags, LPVOID base, SIZE_T size, LPVOID *addresses,
                           ULONG_PTR *count, ULONG *granularity )
{
    NTSTATUS status;

    status = NtGetWriteWatch( GetCurrentProcess(), flags, base, size, addresses, count, granularity );
    if (status) SetLastError( RtlNtStatusToDosError(status) );
    return status ? ~0u : 0;
}


/***********************************************************************
 *             ResetWriteWatch   (KERNEL32.@)
 */
UINT WINAPI ResetWriteWatch( LPVOID base, SIZE_T size )
{
    NTSTATUS status;

    status = NtResetWriteWatch( GetCurrentProcess(), base, size );
    if (status) SetLastError( RtlNtStatusToDosError(status) );
    return status ? ~0u : 0;
}


459 460 461
/***********************************************************************
 *             IsBadReadPtr   (KERNEL32.@)
 *
462 463
 * Check for read access on a memory block.
 *
464 465 466
 * ptr  [I] Address of memory block.
 * size [I] Size of block.
 *
467
 * RETURNS
468 469
 *  Success: TRUE.
 *	Failure: FALSE. Process has read access to entire block.
470
 */
471
BOOL WINAPI IsBadReadPtr( LPCVOID ptr, UINT_PTR size )
472 473
{
    if (!size) return FALSE;  /* handle 0 size case w/o reference */
474
    if (!ptr) return TRUE;
475
    __TRY
Alexandre Julliard's avatar
Alexandre Julliard committed
476
    {
477
        volatile const char *p = ptr;
478
        char dummy __attribute__((unused));
479
        UINT_PTR count = size;
480

481
        while (count > system_info.PageSize)
Alexandre Julliard's avatar
Alexandre Julliard committed
482
        {
483
            dummy = *p;
484 485
            p += system_info.PageSize;
            count -= system_info.PageSize;
Alexandre Julliard's avatar
Alexandre Julliard committed
486
        }
487 488
        dummy = p[0];
        dummy = p[count - 1];
Alexandre Julliard's avatar
Alexandre Julliard committed
489
    }
490
    __EXCEPT_PAGE_FAULT
491 492 493 494
    {
        TRACE_(seh)("%p caused page fault during read\n", ptr);
        return TRUE;
    }
495 496 497
    __ENDTRY
    return FALSE;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
498

499

500 501 502
/***********************************************************************
 *             IsBadWritePtr   (KERNEL32.@)
 *
503 504
 * Check for write access on a memory block.
 *
505 506 507 508
 * PARAMS
 *  ptr  [I] Address of memory block.
 *  size [I] Size of block in bytes.
 *
509
 * RETURNS
510 511
 *  Success: TRUE.
 *	Failure: FALSE. Process has write access to entire block.
512
 */
513
BOOL WINAPI IsBadWritePtr( LPVOID ptr, UINT_PTR size )
514 515
{
    if (!size) return FALSE;  /* handle 0 size case w/o reference */
516
    if (!ptr) return TRUE;
517 518 519
    __TRY
    {
        volatile char *p = ptr;
520
        UINT_PTR count = size;
521

522
        while (count > system_info.PageSize)
523 524
        {
            *p |= 0;
525 526
            p += system_info.PageSize;
            count -= system_info.PageSize;
527 528 529 530
        }
        p[0] |= 0;
        p[count - 1] |= 0;
    }
531
    __EXCEPT_PAGE_FAULT
532 533 534 535
    {
        TRACE_(seh)("%p caused page fault during write\n", ptr);
        return TRUE;
    }
536 537 538
    __ENDTRY
    return FALSE;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
539 540


541 542
/***********************************************************************
 *             IsBadHugeReadPtr   (KERNEL32.@)
543 544 545
 *
 * Check for read access on a memory block.
 *
546 547 548 549
 * PARAMS
 *  ptr  [I] Address of memory block.
 *  size [I] Size of block.
 *
550
 * RETURNS
551 552
 *  Success: TRUE.
 *	Failure: FALSE. Process has read access to entire block.
553
 */
554
BOOL WINAPI IsBadHugeReadPtr( LPCVOID ptr, UINT_PTR size )
555
{
556 557
    return IsBadReadPtr( ptr, size );
}
Alexandre Julliard's avatar
Alexandre Julliard committed
558 559


560 561
/***********************************************************************
 *             IsBadHugeWritePtr   (KERNEL32.@)
562 563 564
 *
 * Check for write access on a memory block.
 *
565 566 567 568
 * PARAMS
 *  ptr  [I] Address of memory block.
 *  size [I] Size of block.
 *
569
 * RETURNS
570 571
 *  Success: TRUE.
 *	Failure: FALSE. Process has write access to entire block.
572
 */
573
BOOL WINAPI IsBadHugeWritePtr( LPVOID ptr, UINT_PTR size )
574
{
575
    return IsBadWritePtr( ptr, size );
Alexandre Julliard's avatar
Alexandre Julliard committed
576 577 578
}


Alexandre Julliard's avatar
Alexandre Julliard committed
579
/***********************************************************************
580
 *             IsBadCodePtr   (KERNEL32.@)
Alexandre Julliard's avatar
Alexandre Julliard committed
581
 *
582 583
 * Check for read access on a memory address.
 *
584 585 586
 * PARAMS
 *  ptr [I] Address of function.
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
587
 * RETURNS
588 589
 *	Success: TRUE.
 *	Failure: FALSE. Process has read access to specified memory.
Alexandre Julliard's avatar
Alexandre Julliard committed
590
 */
591
BOOL WINAPI IsBadCodePtr( FARPROC ptr )
592 593 594
{
    return IsBadReadPtr( ptr, 1 );
}
Alexandre Julliard's avatar
Alexandre Julliard committed
595 596


597 598 599
/***********************************************************************
 *             IsBadStringPtrA   (KERNEL32.@)
 *
600 601
 * Check for read access on a range of memory pointed to by a string pointer.
 *
602 603 604 605
 * PARAMS
 *  str [I] Address of string.
 *  max [I] Maximum size of string.
 *
606
 * RETURNS
607 608
 *	Success: TRUE.
 *	Failure: FALSE. Read access to all bytes in string.
609
 */
610
BOOL WINAPI IsBadStringPtrA( LPCSTR str, UINT_PTR max )
611
{
612 613
    if (!str) return TRUE;
    
614
    __TRY
Alexandre Julliard's avatar
Alexandre Julliard committed
615
    {
616 617
        volatile const char *p = str;
        while (p != str + max) if (!*p++) break;
Alexandre Julliard's avatar
Alexandre Julliard committed
618
    }
619
    __EXCEPT_PAGE_FAULT
620 621 622 623
    {
        TRACE_(seh)("%p caused page fault during read\n", str);
        return TRUE;
    }
624
    __ENDTRY
Alexandre Julliard's avatar
Alexandre Julliard committed
625 626
    return FALSE;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
627

Alexandre Julliard's avatar
Alexandre Julliard committed
628

Alexandre Julliard's avatar
Alexandre Julliard committed
629
/***********************************************************************
630
 *             IsBadStringPtrW   (KERNEL32.@)
631
 *
632
 * See IsBadStringPtrA.
Alexandre Julliard's avatar
Alexandre Julliard committed
633
 */
634
BOOL WINAPI IsBadStringPtrW( LPCWSTR str, UINT_PTR max )
635
{
636 637
    if (!str) return TRUE;
    
638
    __TRY
Alexandre Julliard's avatar
Alexandre Julliard committed
639
    {
640 641
        volatile const WCHAR *p = str;
        while (p != str + max) if (!*p++) break;
Alexandre Julliard's avatar
Alexandre Julliard committed
642
    }
643
    __EXCEPT_PAGE_FAULT
644 645 646 647
    {
        TRACE_(seh)("%p caused page fault during read\n", str);
        return TRUE;
    }
648 649
    __ENDTRY
    return FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
650
}
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676

/***********************************************************************
 *           K32GetMappedFileNameA (KERNEL32.@)
 */
DWORD WINAPI K32GetMappedFileNameA(HANDLE process, LPVOID lpv, LPSTR file_name, DWORD size)
{
    FIXME_(file)("(%p, %p, %p, %d): stub\n", process, lpv, file_name, size);

    if (file_name && size)
        file_name[0] = '\0';

    return 0;
}

/***********************************************************************
 *           K32GetMappedFileNameW (KERNEL32.@)
 */
DWORD WINAPI K32GetMappedFileNameW(HANDLE process, LPVOID lpv, LPWSTR file_name, DWORD size)
{
    FIXME_(file)("(%p, %p, %p, %d): stub\n", process, lpv, file_name, size);

    if (file_name && size)
        file_name[0] = '\0';

    return 0;
}
677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694

/***********************************************************************
 *           K32EnumPageFilesA (KERNEL32.@)
 */
BOOL WINAPI K32EnumPageFilesA( PENUM_PAGE_FILE_CALLBACKA callback, LPVOID context )
{
    FIXME_(file)("(%p, %p) stub\n", callback, context );
    return FALSE;
}

/***********************************************************************
 *           K32EnumPageFilesW (KERNEL32.@)
 */
BOOL WINAPI K32EnumPageFilesW( PENUM_PAGE_FILE_CALLBACKW callback, LPVOID context )
{
    FIXME_(file)("(%p, %p) stub\n", callback, context );
    return FALSE;
}
695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723

/***********************************************************************
 *           K32GetWsChanges (KERNEL32.@)
 */
BOOL WINAPI K32GetWsChanges(HANDLE process, PPSAPI_WS_WATCH_INFORMATION watchinfo, DWORD size)
{
    NTSTATUS status;

    TRACE_(seh)("(%p, %p, %d)\n", process, watchinfo, size);

    status = NtQueryInformationProcess( process, ProcessWorkingSetWatch, watchinfo, size, NULL );

    if (status)
    {
        SetLastError( RtlNtStatusToDosError( status ) );
        return FALSE;
    }
    return TRUE;
}

/***********************************************************************
 *           K32InitializeProcessForWsWatch (KERNEL32.@)
 */
BOOL WINAPI K32InitializeProcessForWsWatch(HANDLE process)
{
    FIXME_(seh)("(process=%p): stub\n", process);

    return TRUE;
}