source: trunk/src/ole32/stg_bigblockfile.cpp@ 2013

Last change on this file since 2013 was 1033, checked in by davidr, 26 years ago

Ported remaining files pertaining to OLE32 from WINE

File size: 21.3 KB
Line 
1/* $Id: stg_bigblockfile.cpp,v 1.1 1999-09-24 21:49:44 davidr Exp $ */
2/*
3 * BigBlockFile
4 *
5 * 20/9/99
6 *
7 * Copyright 1999 David J. Raison
8 *
9 * Direct port of Wine Implementation
10 *
11 * This is the implementation of a file that consists of blocks of
12 * a predetermined size.
13 * This class is used in the Compound File implementation of the
14 * IStorage and IStream interfaces. It provides the functionality
15 * to read and write any blocks in the file as well as setting and
16 * obtaining the size of the file.
17 * The blocks are indexed sequentially from the start of the file
18 * starting with -1.
19 *
20 * TODO:
21 * - Support for a transacted mode
22 *
23 * Copyright 1999 Thuy Nguyen
24 */
25
26#include "ole32.h"
27#include "heapstring.h"
28#include "debugtools.h"
29#include "storage.h"
30
31#include <assert.h>
32
33DEFAULT_DEBUG_CHANNEL(storage)
34
35/***********************************************************
36 * Data structures used internally by the BigBlockFile
37 * class.
38 */
39
40/***
41 * Itdentifies a single big block and the related
42 * information
43 */
44struct BigBlock
45{
46 BigBlock * next;
47 DWORD index;
48 DWORD access_mode;
49 LPVOID lpBlock;
50};
51
52/***
53 * This structure identifies the paged that are mapped
54 * from the file and their position in memory. It is
55 * also used to hold a reference count to those pages.
56 */
57struct MappedPage
58{
59 MappedPage * next;
60 DWORD number;
61 int ref;
62 LPVOID lpBytes;
63};
64
65#define PAGE_SIZE 131072
66#define BLOCKS_PER_PAGE 256
67
68#define NUMBER_OF_MAPPED_PAGES 100
69
70/***********************************************************
71 * Prototypes for private methods
72 */
73static void* BIGBLOCKFILE_GetMappedView(LPBIGBLOCKFILE This,
74 DWORD pagenum,
75 DWORD desired_access);
76static void BIGBLOCKFILE_ReleaseMappedPage(LPBIGBLOCKFILE This,
77 DWORD pagenum,
78 DWORD access);
79static void BIGBLOCKFILE_FreeAllMappedPages(LPBIGBLOCKFILE This);
80static void* BIGBLOCKFILE_GetBigBlockPointer(LPBIGBLOCKFILE This,
81 ULONG index,
82 DWORD desired_access);
83static BigBlock* BIGBLOCKFILE_GetBigBlockFromPointer(LPBIGBLOCKFILE This,
84 void* pBlock);
85static void BIGBLOCKFILE_RemoveBlock(LPBIGBLOCKFILE This,
86 ULONG index);
87static BigBlock* BIGBLOCKFILE_AddBigBlock(LPBIGBLOCKFILE This,
88 ULONG index);
89static BigBlock* BIGBLOCKFILE_CreateBlock(ULONG index);
90static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags);
91static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile);
92static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt);
93static void BIGBLOCKFILE_RemoveAllBlocks(LPBIGBLOCKFILE This);
94
95/******************************************************************************
96 * BIGBLOCKFILE_Construct
97 *
98 * Construct a big block file. Create the file mapping object.
99 * Create the read only mapped pages list, the writeable mapped page list
100 * and the blocks in use list.
101 */
102BigBlockFile * BIGBLOCKFILE_Construct(
103 HANDLE hFile,
104 ILockBytes* pLkByt,
105 DWORD openFlags,
106 ULONG blocksize,
107 BOOL fileBased)
108{
109 LPBIGBLOCKFILE This;
110
111 This = (LPBIGBLOCKFILE)HeapAlloc(GetProcessHeap(), 0, sizeof(BigBlockFile));
112
113 if (This == NULL)
114 return NULL;
115
116 This->fileBased = fileBased;
117
118 This->flProtect = BIGBLOCKFILE_GetProtectMode(openFlags);
119
120 This->blocksize = blocksize;
121
122 /* initialize the block list
123 */
124 This->headblock = NULL;
125
126 if (This->fileBased)
127 {
128 if (!BIGBLOCKFILE_FileInit(This, hFile))
129 {
130 HeapFree(GetProcessHeap(), 0, This);
131 return NULL;
132 }
133 }
134 else
135 {
136 if (!BIGBLOCKFILE_MemInit(This, pLkByt))
137 {
138 HeapFree(GetProcessHeap(), 0, This);
139 return NULL;
140 }
141 }
142
143 return This;
144}
145
146/******************************************************************************
147 * BIGBLOCKFILE_FileInit
148 *
149 * Initialize a big block object supported by a file.
150 */
151static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile)
152{
153 This->pLkbyt = NULL;
154 This->hbytearray = 0;
155 This->pbytearray = NULL;
156
157 This->hfile = hFile;
158
159 if (This->hfile == INVALID_HANDLE_VALUE)
160 return FALSE;
161
162 /* create the file mapping object
163 */
164 This->hfilemap = CreateFileMappingA(This->hfile,
165 NULL,
166 This->flProtect,
167 0, 0,
168 NULL);
169
170 if (This->hfilemap == NULL)
171 {
172 CloseHandle(This->hfile);
173 return FALSE;
174 }
175
176 This->filesize.LowPart = GetFileSize(This->hfile, NULL);
177
178 /* create the mapped pages list
179 */
180 This->maplisthead = (MappedPage *)HeapAlloc(GetProcessHeap(), 0, sizeof(MappedPage));
181
182 if (This->maplisthead == NULL)
183 {
184 CloseHandle(This->hfilemap);
185 CloseHandle(This->hfile);
186 return FALSE;
187 }
188
189 This->maplisthead->next = NULL;
190
191 return TRUE;
192}
193
194/******************************************************************************
195 * BIGBLOCKFILE_MemInit
196 *
197 * Initialize a big block object supported by an ILockBytes on HGLOABL.
198 */
199static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt)
200{
201 This->hfile = 0;
202 This->hfilemap = NULL;
203 This->maplisthead = NULL;
204
205 /*
206 * Retrieve the handle to the byte array from the LockByte object.
207 */
208 if (GetHGlobalFromILockBytes(plkbyt, &(This->hbytearray)) != S_OK)
209 {
210 FIXME("May not be an ILockBytes on HGLOBAL\n");
211 return FALSE;
212 }
213
214 This->pLkbyt = plkbyt;
215
216 /*
217 * Increment the reference count of the ILockByte object since
218 * we're keeping a reference to it.
219 */
220 ILockBytes_AddRef(This->pLkbyt);
221
222 This->filesize.LowPart = GlobalSize(This->hbytearray);
223 This->filesize.HighPart = 0;
224
225 This->pbytearray = GlobalLock(This->hbytearray);
226
227 return TRUE;
228}
229
230/******************************************************************************
231 * BIGBLOCKFILE_Destructor
232 *
233 * Destructor. Clean up, free memory.
234 */
235void BIGBLOCKFILE_Destructor(
236 LPBIGBLOCKFILE This)
237{
238 if (This->fileBased)
239 {
240 /* unmap all views and destroy the mapped page list
241 */
242 BIGBLOCKFILE_FreeAllMappedPages(This);
243 HeapFree(GetProcessHeap(), 0, This->maplisthead);
244
245 /* close all open handles
246 */
247 CloseHandle(This->hfilemap);
248 CloseHandle(This->hfile);
249 }
250 else
251 {
252 GlobalUnlock(This->hbytearray);
253 ILockBytes_Release(This->pLkbyt);
254 }
255
256 /*
257 * Destroy the blocks list.
258 */
259 BIGBLOCKFILE_RemoveAllBlocks(This);
260
261 /* destroy this
262 */
263 HeapFree(GetProcessHeap(), 0, This);
264}
265
266/******************************************************************************
267 * BIGBLOCKFILE_GetROBigBlock
268 *
269 * Returns the specified block in read only mode.
270 * Will return NULL if the block doesn't exists.
271 */
272void* BIGBLOCKFILE_GetROBigBlock(
273 LPBIGBLOCKFILE This,
274 ULONG index)
275{
276 /*
277 * block index starts at -1
278 * translate to zero based index
279 */
280 if (index == 0xffffffff)
281 index = 0;
282 else
283 index++;
284
285 /*
286 * validate the block index
287 *
288 */
289 if ((This->blocksize * (index + 1)) >
290 (This->filesize.LowPart +
291 (This->blocksize - (This->filesize.LowPart % This->blocksize))))
292 return 0;
293
294 return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_READ);
295}
296
297/******************************************************************************
298 * BIGBLOCKFILE_GetBigBlock
299 *
300 * Returns the specified block.
301 * Will grow the file if necessary.
302 */
303void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index)
304{
305 /*
306 * block index starts at -1
307 * translate to zero based index
308 */
309 if (index == 0xffffffff)
310 index = 0;
311 else
312 index++;
313
314 /*
315 * make sure that the block physically exists
316 */
317 if ((This->blocksize * (index + 1)) > This->filesize.LowPart)
318 {
319 ULARGE_INTEGER newSize;
320
321 newSize.HighPart = 0;
322 newSize.LowPart = This->blocksize * (index + 1);
323
324 BIGBLOCKFILE_SetSize(This, newSize);
325 }
326
327 return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_WRITE);
328}
329
330/******************************************************************************
331 * BIGBLOCKFILE_ReleaseBigBlock
332 *
333 * Releases the specified block.
334 */
335void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock)
336{
337 DWORD page_num;
338 BigBlock* theBigBlock;
339
340 if (pBlock == NULL)
341 return;
342
343 /*
344 * get the block from the block list
345 */
346 theBigBlock = BIGBLOCKFILE_GetBigBlockFromPointer(This, pBlock);
347
348 if (theBigBlock == NULL)
349 return;
350
351 if (This->fileBased)
352 {
353 /*
354 * find out which page this block is in
355 */
356 page_num = theBigBlock->index / BLOCKS_PER_PAGE;
357
358 /*
359 * release this page
360 */
361 BIGBLOCKFILE_ReleaseMappedPage(This, page_num, theBigBlock->access_mode);
362 }
363
364 /*
365 * remove block from list
366 */
367 BIGBLOCKFILE_RemoveBlock(This, theBigBlock->index);
368}
369
370/******************************************************************************
371 * BIGBLOCKFILE_SetSize
372 *
373 * Sets the size of the file.
374 *
375 */
376void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize)
377{
378 if (This->filesize.LowPart == newSize.LowPart)
379 return;
380
381 if (This->fileBased)
382 {
383 /*
384 * unmap all views, must be done before call to SetEndFile
385 */
386 BIGBLOCKFILE_FreeAllMappedPages(This);
387
388 /*
389 * close file-mapping object, must be done before call to SetEndFile
390 */
391 CloseHandle(This->hfilemap);
392 This->hfilemap = NULL;
393
394 /*
395 * set the new end of file
396 */
397 SetFilePointer(This->hfile, newSize.LowPart, NULL, FILE_BEGIN);
398 SetEndOfFile(This->hfile);
399
400 /*
401 * re-create the file mapping object
402 */
403 This->hfilemap = CreateFileMappingA(This->hfile,
404 NULL,
405 This->flProtect,
406 0, 0,
407 NULL);
408 }
409 else
410 {
411 GlobalUnlock(This->hbytearray);
412
413 /*
414 * Resize the byte array object.
415 */
416 ILockBytes_SetSize(This->pLkbyt, newSize);
417
418 /*
419 * Re-acquire the handle, it may have changed.
420 */
421 GetHGlobalFromILockBytes(This->pLkbyt, &This->hbytearray);
422 This->pbytearray = GlobalLock(This->hbytearray);
423 }
424
425 /*
426 * empty the blocks list.
427 */
428 BIGBLOCKFILE_RemoveAllBlocks(This);
429
430 This->filesize.LowPart = newSize.LowPart;
431 This->filesize.HighPart = newSize.HighPart;
432}
433
434/******************************************************************************
435 * BIGBLOCKFILE_GetSize
436 *
437 * Returns the size of the file.
438 *
439 */
440ULARGE_INTEGER BIGBLOCKFILE_GetSize(LPBIGBLOCKFILE This)
441{
442 return This->filesize;
443}
444
445/******************************************************************************
446 * BIGBLOCKFILE_GetBigBlockPointer [PRIVATE]
447 *
448 * Returns a pointer to the specified block.
449 */
450static void* BIGBLOCKFILE_GetBigBlockPointer(
451 LPBIGBLOCKFILE This,
452 ULONG index,
453 DWORD desired_access)
454{
455 DWORD block_num;
456 void * pBytes;
457 BigBlock *aBigBlock;
458
459 /* get the big block from the list or add it to the list
460 */
461 aBigBlock = BIGBLOCKFILE_AddBigBlock(This, index);
462
463 if (aBigBlock == NULL)
464 return NULL;
465
466 /* we already have an address for this block
467 */
468 if (aBigBlock->lpBlock != NULL)
469 {
470 /* make sure the desired access matches what we already have
471 */
472 if (aBigBlock->access_mode == desired_access)
473 return aBigBlock->lpBlock;
474 else
475 return NULL;
476 }
477
478 /*
479 * else aBigBlock->lpBigBlock == NULL, it's a new block
480 */
481
482 if (This->fileBased)
483 {
484 DWORD page_num;
485
486 /* find out which page this block is in
487 */
488 page_num = index / BLOCKS_PER_PAGE;
489
490 /* offset of the block in the page
491 */
492 block_num = index % BLOCKS_PER_PAGE;
493
494 /* get a pointer to the first byte in the page
495 */
496 pBytes = BIGBLOCKFILE_GetMappedView(This, page_num, desired_access);
497 }
498 else
499 {
500 pBytes = This->pbytearray;
501 block_num = index;
502 }
503
504 if (pBytes == NULL)
505 return NULL;
506
507 /* initialize block
508 */
509 aBigBlock->lpBlock = ((BYTE*)pBytes + (block_num*This->blocksize));
510 aBigBlock->access_mode = desired_access;
511
512 return aBigBlock->lpBlock;
513}
514
515/******************************************************************************
516 * BIGBLOCKFILE_CreateBlock [PRIVATE]
517 *
518 * Creates a node of the blocks list.
519 */
520static BigBlock* BIGBLOCKFILE_CreateBlock(
521 ULONG index)
522{
523 BigBlock *newBigBlock;
524
525 /* create new list node
526 */
527 newBigBlock = (BigBlock *)HeapAlloc(GetProcessHeap(), 0, sizeof(BigBlock));
528
529 if (newBigBlock == NULL)
530 return NULL;
531
532 /* initialize node
533 */
534 newBigBlock->index = index;
535 newBigBlock->lpBlock = NULL;
536
537 return newBigBlock;
538}
539
540/******************************************************************************
541 * BIGBLOCKFILE_AddBigBlock [PRIVATE]
542 *
543 * Returns the specified block from the blocks list.
544 * If the block is not found in the list, we will create it and add it to the
545 * list.
546 */
547static BigBlock* BIGBLOCKFILE_AddBigBlock(
548 LPBIGBLOCKFILE This,
549 ULONG index)
550{
551 BigBlock *current = This->headblock;
552 BigBlock *newBigBlock;
553
554 if (current == NULL) /* empty list */
555 {
556 newBigBlock = BIGBLOCKFILE_CreateBlock(index);
557
558 if (newBigBlock != NULL)
559 {
560 newBigBlock->next = NULL;
561 This->headblock = newBigBlock;
562 }
563
564 return newBigBlock;
565 }
566 else
567 {
568 /*
569 * special handling for head of the list
570 */
571
572 if (current->index == index) /* it's already here */
573 return current;
574 else if (current->index > index) /* insertion at head of the list */
575 {
576 newBigBlock = BIGBLOCKFILE_CreateBlock(index);
577
578 if (newBigBlock != NULL)
579 {
580 newBigBlock->next = current;
581 This->headblock = newBigBlock;
582 }
583
584 return newBigBlock;
585 }
586 }
587
588 /* iterate through rest the list
589 */
590 while (current->next != NULL)
591 {
592 if (current->next->index == index) /* found it */
593 {
594 return current->next;
595 }
596 else if (current->next->index > index) /* it's not in the list */
597 {
598 newBigBlock = BIGBLOCKFILE_CreateBlock(index);
599
600 if (newBigBlock != NULL)
601 {
602 newBigBlock->next = current->next;
603 current->next = newBigBlock;
604 }
605
606 return newBigBlock;
607 }
608 else
609 current = current->next;
610 }
611
612 /*
613 * insertion at end of the list
614 */
615 if (current->next == NULL)
616 {
617 newBigBlock = BIGBLOCKFILE_CreateBlock(index);
618
619 if (newBigBlock != NULL)
620 {
621 newBigBlock->next = NULL;
622 current->next = newBigBlock;
623 }
624
625 return newBigBlock;
626 }
627
628 return NULL;
629}
630
631/******************************************************************************
632 * BIGBLOCKFILE_RemoveAllBlocks [PRIVATE]
633 *
634 * Removes all blocks from the blocks list.
635 */
636static void BIGBLOCKFILE_RemoveAllBlocks(
637 LPBIGBLOCKFILE This)
638{
639 BigBlock *current;
640
641 while (This->headblock != NULL)
642 {
643 current = This->headblock;
644 This->headblock = current->next;
645 HeapFree(GetProcessHeap(), 0, current);
646 }
647}
648
649/******************************************************************************
650 * BIGBLOCKFILE_RemoveBlock [PRIVATE]
651 *
652 * Removes the specified block from the blocks list.
653 */
654static void BIGBLOCKFILE_RemoveBlock(
655 LPBIGBLOCKFILE This,
656 ULONG index)
657{
658 BigBlock *current = This->headblock;
659
660 /*
661 * empty list
662 */
663 if (current == NULL)
664 return;
665
666 /*
667 *special case: removing head of list
668 */
669 if (current->index == index)
670 {
671 /*
672 * set new head free the old one
673 */
674 This->headblock = current->next;
675 HeapFree(GetProcessHeap(), 0, current);
676
677 return;
678 }
679
680 /*
681 * iterate through rest of the list
682 */
683 while (current->next != NULL)
684 {
685 if (current->next->index == index) /* found it */
686 {
687 /*
688 * unlink the block and free the block
689 */
690 current->next = current->next->next;
691 HeapFree(GetProcessHeap(), 0, current->next);
692
693 return;
694 }
695 else
696 {
697 /* next node
698 */
699 current = current->next;
700 }
701 }
702}
703
704/******************************************************************************
705 * BIGBLOCKFILE_GetBigBlockFromPointer [PRIVATE]
706 *
707 * Given a block pointer, this will return the corresponding block
708 * from the blocks list.
709 */
710static BigBlock* BIGBLOCKFILE_GetBigBlockFromPointer(
711 LPBIGBLOCKFILE This,
712 void* pBlock)
713{
714 BigBlock *current = This->headblock;
715
716 while (current != NULL)
717 {
718 if (current->lpBlock == pBlock)
719 {
720 break;
721 }
722 else
723 current = current->next;
724 }
725
726 return current;
727}
728
729/******************************************************************************
730 * BIGBLOCKFILE_GetMappedView [PRIVATE]
731 *
732 * Gets the page requested if it is already mapped.
733 * If it's not already mapped, this method will map it
734 */
735static void * BIGBLOCKFILE_GetMappedView(
736 LPBIGBLOCKFILE This,
737 DWORD pagenum,
738 DWORD desired_access)
739{
740 MappedPage* current = This->maplisthead;
741 ULONG count = 1;
742 BOOL found = FALSE;
743
744 assert(This->maplisthead != NULL);
745
746 /*
747 * Search for the page in the list.
748 */
749 while ((found == FALSE) && (current->next != NULL))
750 {
751 if (current->next->number == pagenum)
752 {
753 found = TRUE;
754
755 /*
756 * If it's not already at the head of the list
757 * move it there.
758 */
759 if (current != This->maplisthead)
760 {
761 MappedPage* temp = current->next;
762
763 current->next = current->next->next;
764
765 temp->next = This->maplisthead->next;
766 This->maplisthead->next = temp;
767 }
768 }
769
770 /*
771 * The list is full and we haven't found it.
772 * Free the last element of the list because we'll add a new
773 * one at the head.
774 */
775 if ((found == FALSE) &&
776 (count >= NUMBER_OF_MAPPED_PAGES) &&
777 (current->next != NULL))
778 {
779 UnmapViewOfFile(current->next->lpBytes);
780
781 HeapFree(GetProcessHeap(), 0, current->next);
782 current->next = NULL;
783 }
784
785 if (current->next != NULL)
786 current = current->next;
787
788 count++;
789 }
790
791 /*
792 * Add the page at the head of the list.
793 */
794 if (found == FALSE)
795 {
796 MappedPage* newMappedPage;
797 DWORD numBytesToMap;
798 DWORD hioffset = 0;
799 DWORD lowoffset = PAGE_SIZE * pagenum;
800
801 newMappedPage = (MappedPage *)HeapAlloc(GetProcessHeap(), 0, sizeof(MappedPage));
802
803 if (newMappedPage == NULL)
804 return NULL;
805
806 newMappedPage->number = pagenum;
807 newMappedPage->ref = 0;
808
809 newMappedPage->next = This->maplisthead->next;
810 This->maplisthead->next = newMappedPage;
811
812 if (((pagenum + 1) * PAGE_SIZE) > This->filesize.LowPart)
813 numBytesToMap = This->filesize.LowPart - (pagenum * PAGE_SIZE);
814 else
815 numBytesToMap = PAGE_SIZE;
816
817 if (This->flProtect == PAGE_READONLY)
818 desired_access = FILE_MAP_READ;
819 else
820 desired_access = FILE_MAP_WRITE;
821
822 newMappedPage->lpBytes = MapViewOfFile(This->hfilemap,
823 desired_access,
824 hioffset,
825 lowoffset,
826 numBytesToMap);
827 }
828
829 /*
830 * The page we want should now be at the head of the list.
831 */
832 assert(This->maplisthead->next != NULL);
833
834 current = This->maplisthead->next;
835 current->ref++;
836
837 return current->lpBytes;
838}
839
840/******************************************************************************
841 * BIGBLOCKFILE_ReleaseMappedPage [PRIVATE]
842 *
843 * Decrements the reference count of the mapped page.
844 */
845static void BIGBLOCKFILE_ReleaseMappedPage(
846 LPBIGBLOCKFILE This,
847 DWORD pagenum,
848 DWORD access)
849{
850 MappedPage* previous = This->maplisthead;
851 MappedPage* current;
852
853 assert(This->maplisthead->next != NULL);
854
855 current = previous->next;
856
857 /* search for the page in the list
858 */
859 while (current != NULL)
860 {
861 if (current->number == pagenum)
862 {
863 /* decrement the reference count
864 */
865 current->ref--;
866 return;
867 }
868 else
869 {
870 previous = current;
871 current = current->next;
872 }
873 }
874}
875
876/******************************************************************************
877 * BIGBLOCKFILE_FreeAllMappedPages [PRIVATE]
878 *
879 * Unmap all currently mapped pages.
880 * Empty mapped pages list.
881 */
882static void BIGBLOCKFILE_FreeAllMappedPages(
883 LPBIGBLOCKFILE This)
884{
885 MappedPage * current = This->maplisthead->next;
886
887 while (current != NULL)
888 {
889 /* Unmap views.
890 */
891 UnmapViewOfFile(current->lpBytes);
892
893 /* Free the nodes.
894 */
895 This->maplisthead->next = current->next;
896 HeapFree(GetProcessHeap(), 0, current);
897
898 current = This->maplisthead->next;
899 }
900}
901
902/****************************************************************************
903 * BIGBLOCKFILE_GetProtectMode
904 *
905 * This function will return a protection mode flag for a file-mapping object
906 * from the open flags of a file.
907 */
908static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags)
909{
910 DWORD flProtect = PAGE_READONLY;
911 BOOL bSTGM_WRITE = ((openFlags & STGM_WRITE) == STGM_WRITE);
912 BOOL bSTGM_READWRITE = ((openFlags & STGM_READWRITE) == STGM_READWRITE);
913 BOOL bSTGM_READ = ! (bSTGM_WRITE || bSTGM_READWRITE);
914
915 if (bSTGM_READ)
916 flProtect = PAGE_READONLY;
917
918 if ((bSTGM_WRITE) || (bSTGM_READWRITE))
919 flProtect = PAGE_READWRITE;
920
921 return flProtect;
922}
923
924
Note: See TracBrowser for help on using the repository browser.