2 * reactos Cache Manager (Cc*) map Bcb handling of libcaptive
3 * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
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
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.
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
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"
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.
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.
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.
61 * This call does not set the buffer as dirty - such buffer will not be flushed automatically.
63 * Every call to this function must be matched by a one corresponding CcUnpinData() call.
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.
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.
74 BOOLEAN CcMapData(IN PFILE_OBJECT FileObject,
75 IN PLARGE_INTEGER FileOffset,IN ULONG Length,IN ULONG Flags,OUT PVOID *Bcb,OUT PVOID *Buffer)
77 CaptiveSharedCacheMapObject *SharedCacheMap;
78 CaptivePrivateBcbMapObject *captive_private_bcb_map_object;
80 g_return_val_if_fail(FileObject!=NULL,FALSE);
81 g_return_val_if_fail(FileOffset!=NULL,FALSE);
82 g_return_val_if_fail(FileOffset->QuadPart>=0,FALSE);
83 g_return_val_if_fail(Length>0,FALSE); /* FIXME: not handled below; 0 should be allowed */
84 g_return_val_if_fail(Flags==MAP_WAIT,FALSE); /* FIXME */
85 g_return_val_if_fail(Bcb!=NULL,FALSE);
86 g_return_val_if_fail(Buffer!=NULL,FALSE);
88 g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s: FileObject=%p,FileOffset=0x%llX,Length=0x%lX,Flags=0x%lX",G_STRLOC,
89 FileObject,(guint64)FileOffset->QuadPart,(gulong)Length,(gulong)Flags);
91 SharedCacheMap=captive_FileObject_to_SharedCacheMap(FileObject);
92 captive_private_bcb_map_object=captive_private_bcb_map_object_get_ref(SharedCacheMap);
94 captive_shared_cache_map_data_validate_read(SharedCacheMap,FileObject,FileOffset->QuadPart,FileOffset->QuadPart+Length);
96 *Bcb=captive_private_bcb_object_get_PublicBcb(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_map_object));
97 *Buffer=captive_shared_cache_map_get_buffer(SharedCacheMap)+FileOffset->QuadPart;
105 * @Bcb: Initialized #PUBLIC_BCB structure.
106 * %NULL value is forbidden.
108 * Create a copy of @Bcb for the exactly same file contents as is @Bcb.
109 * The returned copy has the same attributes as the result of CcMapData()
110 * notwithstanding the current state of input @Bcb, therefore it is only
111 * for read/only access etc.
113 * libcaptive calls CcMapData() internally with @Bcb parameters.
115 * This function is called only by ntfs.sys of NT-5.1sp1 and it will perform
116 * these operations with the resulting #PUBLIC_BCB:
117 * CcRemapBcb(), CcSetDirtyPinnedData(), CcUnpinData()
119 * Untested: This call does not set the buffer as dirty - such buffer will not be flushed automatically.
121 * Returns: Copy of @Bcb. This _pointer_ never equals to @Bcb.
122 * It should be some different
123 * #PUBLIC_BCB structure according to W32 doc.
125 PVOID CcRemapBcb(IN PVOID Bcb)
127 CaptivePrivateBcbObject *captive_private_bcb_object;
128 CaptiveSharedCacheMapObject *SharedCacheMap;
129 CaptivePrivateBcbMapObject *captive_private_bcb_map_object;
130 PUBLIC_BCB *PublicBcb;
132 g_return_val_if_fail(Bcb!=NULL,NULL);
134 captive_private_bcb_object=captive_PublicBcb_to_PrivateBcbObject(Bcb);
135 SharedCacheMap=captive_private_bcb_object_get_SharedCacheMap(captive_private_bcb_object);
137 /* 'Bcb' may even belong to SharedCacheMap without any existing map Bcb (just pin Bcbs). */
138 captive_private_bcb_map_object=captive_private_bcb_map_object_get_ref(SharedCacheMap);
140 PublicBcb=captive_private_bcb_object_get_PublicBcb(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_map_object));