Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / libcaptive / cc / bcbmap.c
1 /* $Id$
2  * reactos Cache Manager (Cc*) map Bcb handling of libcaptive
3  * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 #include "config.h"
21
22 #include "privatebcbmap.h"
23 #include "reactos/ntos/types.h"
24 #include "reactos/ddk/iotypes.h"
25 #include "reactos/ddk/cctypes.h"
26 #include "reactos/ddk/ccfuncs.h"
27 #include "sharedcachemap.h"
28 #include "privatebcb.h"
29
30
31 /**
32  * CcMapData:
33  * @FileObject: Initialized open #FileObject to map.
34  * %NULL value is forbidden.
35  * @FileOffset: The @FileObject file offset from where to map the region from.
36  * Negative value is forbidden.
37  * @Length: Requested length of the region to map from @FileObject.
38  * FIXME: Value %0 is currently forbidden by libcaptive; it should be allowed.
39  * @Flags: %MAP_WAIT means whether disk waiting is permitted for this function.
40  * Value without %MAP_WAIT is currently forbidden by libcaptive as we have no on-demand loading implemented.
41  * %MAP_NO_READ will leave the pages unread (libcaptive: unread pages zeroed,
42  * already mapped pages shared with existing content) - needed by ntfs.sys of NT-5.1sp1
43  * as during file write it will %MAP_NO_READ and consequently push the data there;
44  * any request for the same file range read in the meantime will destroy the prepared data!
45  * @Bcb: Returns initialized #PUBLIC_BCB to refer to the mapped region.
46  * The memory region can be larger than requested as it is %PAGE_SIZE aligned.
47  * %NULL pointer is forbidden.
48  * @Buffer: Returns the mapped memory region start address.
49  * This address may not be %PAGE_SIZE aligned.
50  * %NULL pointer is forbidden.
51  *
52  * Maps the specified region of @FileObject to automatically chosen address space.
53  * FIXME: No on-demand loading implemented yet - the whole region is read at the time of this function call.
54  *
55  * WARNING: If you modify the data in the returned @Buffer you must call some CcPinMappedData()
56  * or CcPinRead() afterwards. W32 docs say you should never modify the data in any way from this function
57  * but W32 filesystems apparently do not conform to it. If you do not take care of the
58  * modified data by some dirty-marking facility such data will be carelessly dropped without
59  * their commit to the disk.
60  *
61  * This call does not set the buffer as dirty - such buffer will not be flushed automatically.
62  *
63  * Every call to this function must be matched by a one corresponding CcUnpinData() call.
64  *
65  * We can be called as full CcMapData() (e.g. CcPinRead() from fastfat.sys)
66  * even if such mapping for such file already exists.
67  * We should probably create a new #Bcb for the same space,
68  * at least ntfs.sys of NT-5.1sp1 appears to expect it. Bleech.
69  *
70  * Returns: %TRUE if the region was successfuly mapped.
71  * @Bcb with the initialized new memory region.
72  * @Buffer with the address of the exact byte specified by @FileOffset.
73  */
74 BOOLEAN CcMapData(IN PFILE_OBJECT FileObject,
75                 IN PLARGE_INTEGER FileOffset,IN ULONG Length,IN ULONG Flags,OUT PVOID *Bcb,OUT PVOID *Buffer)
76 {
77 CaptiveSharedCacheMapObject *SharedCacheMap;
78 CaptivePrivateBcbMapObject *captive_private_bcb_map_object;
79 BOOLEAN r;
80
81         g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"enter: CcMapData: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Flags=0x%lX",
82                         (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Flags);
83
84         g_return_val_if_fail(FileObject!=NULL,FALSE);
85         g_return_val_if_fail(FileOffset!=NULL,FALSE);
86         g_return_val_if_fail(FileOffset->QuadPart>=0,FALSE);
87         g_return_val_if_fail(Length>0,FALSE);   /* FIXME: not handled below; 0 should be allowed */
88         g_return_val_if_fail(Flags==MAP_WAIT,FALSE);    /* FIXME */
89         g_return_val_if_fail(Bcb!=NULL,FALSE);
90         g_return_val_if_fail(Buffer!=NULL,FALSE);
91
92         SharedCacheMap=captive_FileObject_to_SharedCacheMap(FileObject);
93         captive_private_bcb_map_object=captive_private_bcb_map_object_get_ref(SharedCacheMap);
94
95         captive_shared_cache_map_data_validate_read(SharedCacheMap,FileObject,FileOffset->QuadPart,FileOffset->QuadPart+Length);
96
97         *Bcb=captive_private_bcb_object_get_PublicBcb(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_map_object));
98         *Buffer=captive_shared_cache_map_get_buffer(SharedCacheMap)+FileOffset->QuadPart;
99         r=TRUE;
100
101         g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"leave: CcMapData: r=%d,Bcb=0x%lX,Buffer=0x%lX",
102                                 r,(!Bcb ? -1 : (long)*Bcb),(!Buffer ? -1 : (long)*Buffer));
103
104         return r;
105 }
106
107
108 /**
109  * CcRemapBcb:
110  * @Bcb: Initialized #PUBLIC_BCB structure.
111  * %NULL value is forbidden.
112  *
113  * Create a copy of @Bcb for the exactly same file contents as is @Bcb.
114  * The returned copy has the same attributes as the result of CcMapData()
115  * notwithstanding the current state of input @Bcb, therefore it is only
116  * for read/only access etc.
117  *
118  * libcaptive calls CcMapData() internally with @Bcb parameters.
119  *
120  * This function is called only by ntfs.sys of NT-5.1sp1 and it will perform
121  * these operations with the resulting #PUBLIC_BCB:
122  * CcRemapBcb(), CcSetDirtyPinnedData(), CcUnpinData()
123  *
124  * Untested: This call does not set the buffer as dirty - such buffer will not be flushed automatically.
125  *
126  * Returns: Copy of @Bcb. This _pointer_ never equals to @Bcb.
127  * It should be some different
128  * #PUBLIC_BCB structure according to W32 doc.
129  */
130 PVOID CcRemapBcb(IN PVOID Bcb)
131 {
132 CaptivePrivateBcbObject *captive_private_bcb_object;
133 CaptiveSharedCacheMapObject *SharedCacheMap;
134 CaptivePrivateBcbMapObject *captive_private_bcb_map_object;
135 PUBLIC_BCB *PublicBcb;
136
137         g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"enter: CcRemapBcb: Bcb=0x%lX",(long)Bcb);
138
139         g_return_val_if_fail(Bcb!=NULL,NULL);
140
141         captive_private_bcb_object=captive_PublicBcb_to_PrivateBcbObject(Bcb);
142         SharedCacheMap=captive_private_bcb_object_get_SharedCacheMap(captive_private_bcb_object);
143
144         /* 'Bcb' may even belong to SharedCacheMap without any existing map Bcb (just pin Bcbs). */
145         captive_private_bcb_map_object=captive_private_bcb_map_object_get_ref(SharedCacheMap);
146
147         PublicBcb=captive_private_bcb_object_get_PublicBcb(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_map_object));
148
149         g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"leave: CcRemapBcb: r=0x%lX",(long)PublicBcb);
150
151         return PublicBcb;
152 }