Initial revision
[reactos.git] / reactos / ntoskrnl / mm / lock.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: mkernel/mm/lock.c
5 * PURPOSE: Locking/unlocking virtual memory areas
6 * PROGRAMMER: David Welch (welch@mcmail.com)
7 */
8
9 BOOL VirtualUnlock(LPVOID lpAddress, DWORD cbSize)
10 /*
11 * FUNCTION: Unlocks pages from the virtual address space of the current
12 * process
13 * ARGUMENTS:
14 * lpAddress = Beginning of the region to unlock
15 * cbSize = Size (in bytes) of the region to unlock
16 * RETURNS: Success or failure
17 */
18 {
19 return(FALSE);
20 }
21
22 BOOL VirtualLock(LPVOID lpvAddress, DWORD cbSize)
23 /*
24 * FUNCTION: Prevents range of memory from being swapped out
25 * RECEIVES:
26 * lpvAddress - The base of the range to lock
27 * cbSize - The size of the range to lock
28 * RETURNS:
29 * TRUE - the function succeeds
30 * FALSE - the function failed (use GetLastError for details)
31 *
32 * NOTES: I'm guessing the kernel loads every page as well as locking it.
33 */
34 {
35 unsigned int first_page = PAGE_ROUND_DOWN((int)lpvAddress);
36 unsigned int length = PAGE_ROUND_DOWN( ((int)lpvAddress) + cbSize) -
37 first_page;
38 memory_area* marea=NULL;
39 memory_area* current=NULL;
40 unsigned int i;
41
42 /*
43 * Check the process isn't trying to lock too much
44 */
45 if ( ((length/PAGESIZE)+1) > 30)
46 {
47 SetLastError(0);
48 return(FALSE);
49 }
50
51 /*
52 * Find the corresponding vmarea(s)
53 */
54 marea = find_first_marea(memory_area_list_head,first_page,
55 length);
56 if (marea==NULL)
57 {
58 SetLastError(0);
59 return(FALSE);
60 }
61
62 /*
63 * Check the memory areas are committed, continuous and not
64 * PAGE_NOACCESS
65 */
66 current=marea;
67 if (current->base != first_page)
68 {
69 SetLastError(0);
70 return(FALSE);
71 }
72 while (current!=NULL && current->base < (first_page+length) )
73 {
74 if (!(current->state & MEM_COMMIT) ||
75 current->access & PAGE_NOACCESS)
76 {
77 SetLastError(0);
78 return(FALSE);
79 }
80 if ( current->next==NULL)
81 {
82 if ((current->base + current->length) !=
83 (first_page+length) )
84 {
85 SetLastError(0);
86 return(FALSE);
87 }
88 }
89 else
90 {
91 if ( (current->base+current->length) !=
92 current->next->base)
93 {
94 SetLastError(0);
95 return(FALSE);
96 }
97 }
98 current=current->next;
99 }
100
101 /*
102 * Lock/load the areas in memory
103 * (the pages aren't loaded just by touching them to avoid the
104 * overhead of a page fault)
105 */
106 current=marea;
107 while (current!=NULL && current->base < (first_page+length) )
108 {
109 marea->lock = TRUE;
110 for (i=0; i<current->length; i++)
111 {
112 if (!current->load_page(marea,i))
113 {
114 /*
115 * If the page couldn't be loaded we unlock
116 * the locked pages and abort
117 */
118 VirtualUnlock(lpvAddress,
119 current->base+i-PAGESIZE);
120 SetLastError(0);
121 return(FALSE);
122 }
123 }
124 }
125
126 return(TRUE);
127 }