Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

cmwrapr.c File Reference

#include "cmp.h"

Go to the source code of this file.

Defines

#define MAX_FILE_IO   0x10000
#define CmpIoFileRead   1
#define CmpIoFileWrite   2
#define CmpIoFileSetSize   3
#define CmpIoFileFlush   4

Functions

PVOID CmpAllocate (ULONG Size, BOOLEAN UseForIo)
VOID CmpFree (PVOID MemoryBlock, ULONG GlobalQuotaSize)
NTSTATUS CmpDoFileSetSize (PHHIVE Hive, ULONG FileType, ULONG FileSize)
NTSTATUS CmpCreateEvent (IN EVENT_TYPE eventType, OUT PHANDLE eventHandle, OUT PKEVENT *event)
BOOLEAN CmpFileRead (PHHIVE Hive, ULONG FileType, PULONG FileOffset, PVOID DataBuffer, ULONG DataLength)
BOOLEAN CmpFileWrite (PHHIVE Hive, ULONG FileType, PCMP_OFFSET_ARRAY offsetArray, ULONG offsetArrayCount, PULONG FileOffset)
BOOLEAN CmpFileFlush (PHHIVE Hive, ULONG FileType)

Variables

ULONG perftouchbuffer = 0
BOOLEAN CmpNoWrite
struct {
   ULONG   Action
   HANDLE   Handle
   NTSTATUS   Status
CmRegistryIODebug


Define Documentation

#define CmpIoFileFlush   4
 

Definition at line 49 of file cmwrapr.c.

Referenced by CmpFileFlush().

#define CmpIoFileRead   1
 

Definition at line 46 of file cmwrapr.c.

Referenced by CmpFileRead().

#define CmpIoFileSetSize   3
 

Definition at line 48 of file cmwrapr.c.

Referenced by CmpDoFileSetSize().

#define CmpIoFileWrite   2
 

Definition at line 47 of file cmwrapr.c.

Referenced by CmpFileWrite().

#define MAX_FILE_IO   0x10000
 

Definition at line 44 of file cmwrapr.c.

Referenced by CmpFileRead(), and CmpFileWrite().


Function Documentation

PVOID CmpAllocate ULONG  Size,
BOOLEAN  UseForIo
 

Definition at line 62 of file cmwrapr.c.

References CML_MINOR, CMLOG, CmpClaimGlobalQuota(), CmpReleaseGlobalQuota(), CMS_POOL, ExAllocatePoolWithTag, FALSE, NULL, PagedPool, PagedPoolCacheAligned, RtlGetCallersAddress(), and Size.

Referenced by CmpInitializeHive().

00068 : 00069 00070 This routine makes more memory available to a hive. 00071 00072 It is environment specific. 00073 00074 Arguments: 00075 00076 Size - amount of space caller wants 00077 00078 UseForIo - TRUE if object allocated will be target of I/O, 00079 FALSE if not. 00080 00081 Return Value: 00082 00083 NULL if failure, address of allocated block if not. 00084 00085 --*/ 00086 { 00087 PVOID result; 00088 ULONG pooltype; 00089 #if DBG 00090 PVOID Caller; 00091 PVOID CallerCaller; 00092 RtlGetCallersAddress(&Caller, &CallerCaller); 00093 #endif 00094 00095 if (CmpClaimGlobalQuota(Size) == FALSE) { 00096 return NULL; 00097 } 00098 00099 pooltype = (UseForIo) ? PagedPoolCacheAligned : PagedPool; 00100 result = ExAllocatePoolWithTag( 00101 pooltype, 00102 Size, 00103 CM_POOL_TAG 00104 ); 00105 00106 #if DBG 00107 CMLOG(CML_MINOR, CMS_POOL) { 00108 KdPrint(("**CmpAllocate: allocate:%08lx, ", Size)); 00109 KdPrint(("type:%d, at:%08lx ", PagedPool, result)); 00110 KdPrint(("c:%08lx cc:%08lx\n", Caller, CallerCaller)); 00111 } 00112 #endif 00113 00114 if (result == NULL) { 00115 CmpReleaseGlobalQuota(Size); 00116 } 00117 00118 return result; 00119 }

NTSTATUS CmpCreateEvent IN EVENT_TYPE  eventType,
OUT PHANDLE  eventHandle,
OUT PKEVENT event
 

Definition at line 313 of file cmwrapr.c.

References FALSE, KernelMode, NT_SUCCESS, NTSTATUS(), NULL, and ObReferenceObjectByHandle().

Referenced by CmpFileRead(), CmpFileWrite(), and CmpOpenHiveFiles().

00318 { 00319 NTSTATUS status; 00320 OBJECT_ATTRIBUTES obja; 00321 00322 InitializeObjectAttributes( &obja, NULL, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL ); 00323 status = ZwCreateEvent( 00324 eventHandle, 00325 EVENT_ALL_ACCESS, 00326 &obja, 00327 eventType, 00328 FALSE); 00329 00330 if (!NT_SUCCESS(status)) { 00331 return status; 00332 } 00333 00334 status = ObReferenceObjectByHandle( 00335 *eventHandle, 00336 EVENT_ALL_ACCESS, 00337 NULL, 00338 KernelMode, 00339 event, 00340 NULL); 00341 00342 if (!NT_SUCCESS(status)) { 00343 ZwClose(*eventHandle); 00344 return status; 00345 } 00346 return status; 00347 }

NTSTATUS CmpDoFileSetSize PHHIVE  Hive,
ULONG  FileType,
ULONG  FileSize
 

Definition at line 227 of file cmwrapr.c.

References ASSERT, ASSERT_PASSIVE_LEVEL, CmpIoFileSetSize, CmRegistryIODebug, DbgPrint, FALSE, _CMHIVE::FileHandles, Hive, IoSetThreadHardErrorMode(), L, NT_SUCCESS, NTSTATUS(), NULL, Status, TRUE, and ZwSetInformationFile().

Referenced by CmpFileSetSize(), CmpWorker(), CmpWorkerCommand(), HvpDoWriteHive(), and HvWriteHive().

00234 : 00235 00236 This routine sets the size of a file. It must not return until 00237 the size is guaranteed. 00238 00239 It is environment specific. 00240 00241 Must be running in the context of the cmp worker thread. 00242 00243 Arguments: 00244 00245 Hive - Hive we are doing I/O for 00246 00247 FileType - which supporting file to use 00248 00249 FileSize - 32 bit value to set the file's size to 00250 00251 Return Value: 00252 00253 FALSE if failure 00254 TRUE if success 00255 00256 --*/ 00257 { 00258 PCMHIVE CmHive; 00259 HANDLE FileHandle; 00260 NTSTATUS Status; 00261 FILE_END_OF_FILE_INFORMATION FileInfo; 00262 IO_STATUS_BLOCK IoStatus; 00263 BOOLEAN oldFlag; 00264 00265 ASSERT(FIELD_OFFSET(CMHIVE, Hive) == 0); 00266 00267 CmHive = (PCMHIVE)Hive; 00268 FileHandle = CmHive->FileHandles[FileType]; 00269 if (FileHandle == NULL) { 00270 return TRUE; 00271 } 00272 00273 // 00274 // disable hard error popups, to avoid self deadlock on bogus devices 00275 // 00276 oldFlag = IoSetThreadHardErrorMode(FALSE); 00277 00278 FileInfo.EndOfFile.HighPart = 0L; 00279 FileInfo.EndOfFile.LowPart = FileSize; 00280 00281 ASSERT_PASSIVE_LEVEL(); 00282 00283 Status = ZwSetInformationFile( 00284 FileHandle, 00285 &IoStatus, 00286 (PVOID)&FileInfo, 00287 sizeof(FILE_END_OF_FILE_INFORMATION), 00288 FileEndOfFileInformation 00289 ); 00290 00291 if (NT_SUCCESS(Status)) { 00292 ASSERT(IoStatus.Status == Status); 00293 } else { 00294 00295 // 00296 // set debugging info 00297 // 00298 CmRegistryIODebug.Action = CmpIoFileSetSize; 00299 CmRegistryIODebug.Handle = FileHandle; 00300 CmRegistryIODebug.Status = Status; 00301 DbgPrint("CmpFileSetSize:\tHandle=%08lx NewLength=%08lx \n", FileHandle, FileSize); 00302 } 00303 00304 // 00305 // restore hard error popups mode 00306 // 00307 IoSetThreadHardErrorMode(oldFlag); 00308 00309 return Status; 00310 }

BOOLEAN CmpFileFlush PHHIVE  Hive,
ULONG  FileType
 

Definition at line 772 of file cmwrapr.c.

References ASSERT, ASSERT_PASSIVE_LEVEL, CML_MAJOR, CMLOG, CmpIoFileFlush, CmpNoWrite, CmRegistryIODebug, CMS_IO, DbgPrint, FALSE, _CMHIVE::FileHandles, Hive, NT_SUCCESS, NTSTATUS(), NULL, and TRUE.

Referenced by CmpInitializeHive(), and CmpSaveKeyByFileCopy().

00778 : 00779 00780 This routine performs a flush on a file handle. 00781 00782 Arguments: 00783 00784 Hive - Hive we are doing I/O for 00785 00786 FileType - which supporting file to use 00787 00788 Return Value: 00789 00790 FALSE if failure 00791 TRUE if success 00792 00793 --*/ 00794 { 00795 NTSTATUS status; 00796 IO_STATUS_BLOCK IoStatus; 00797 PCMHIVE CmHive; 00798 HANDLE FileHandle; 00799 00800 ASSERT(FIELD_OFFSET(CMHIVE, Hive) == 0); 00801 CmHive = (PCMHIVE)Hive; 00802 FileHandle = CmHive->FileHandles[FileType]; 00803 if (FileHandle == NULL) { 00804 return TRUE; 00805 } 00806 00807 if (CmpNoWrite) { 00808 return TRUE; 00809 } 00810 00811 CMLOG(CML_MAJOR, CMS_IO) { 00812 KdPrint(("CmpFileFlush:\n\tHandle = %08lx\n", FileHandle)); 00813 } 00814 00815 ASSERT_PASSIVE_LEVEL(); 00816 00817 status = ZwFlushBuffersFile( 00818 FileHandle, 00819 &IoStatus 00820 ); 00821 00822 if (NT_SUCCESS(status)) { 00823 ASSERT(IoStatus.Status == status); 00824 return TRUE; 00825 } else { 00826 // 00827 // set debugging info 00828 // 00829 CmRegistryIODebug.Action = CmpIoFileFlush; 00830 CmRegistryIODebug.Handle = FileHandle; 00831 CmRegistryIODebug.Status = status; 00832 DbgPrint("CmpFileFlush:\tFailure1: status = %08lx IoStatus = %08lx\n",status,IoStatus.Status); 00833 return FALSE; 00834 } 00835 return TRUE; 00836 } }

BOOLEAN CmpFileRead PHHIVE  Hive,
ULONG  FileType,
PULONG  FileOffset,
PVOID  DataBuffer,
ULONG  DataLength
 

Definition at line 351 of file cmwrapr.c.

References ASSERT, ASSERT_PASSIVE_LEVEL, CML_MAJOR, CMLOG, CmpCreateEvent(), CmpIoFileRead, CmRegistryIODebug, CMS_IO, CMS_IO_ERROR, DbgPrint, Executive, FALSE, _CMHIVE::FileHandles, Hive, KernelMode, KeWaitForSingleObject(), L, MAX_FILE_IO, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, Offset, and TRUE.

Referenced by CmpInitializeHive(), and CmpWorker().

00360 : 00361 00362 This routine reads in a buffer from a file. 00363 00364 It is environment specific. 00365 00366 NOTE: We assume the handle is opened for asynchronous access, 00367 and that we, and not the IO system, are keeping the 00368 offset pointer. 00369 00370 NOTE: Only 32bit offsets are supported, even though the underlying 00371 IO system on NT supports 64 bit offsets. 00372 00373 Arguments: 00374 00375 Hive - Hive we are doing I/O for 00376 00377 FileType - which supporting file to use 00378 00379 FileOffset - pointer to variable providing 32bit offset on input, 00380 and receiving new 32bit offset on output. 00381 00382 DataBuffer - pointer to buffer 00383 00384 DataLength - length of buffer 00385 00386 Return Value: 00387 00388 FALSE if failure 00389 TRUE if success 00390 00391 --*/ 00392 { 00393 NTSTATUS status; 00394 LARGE_INTEGER Offset; 00395 IO_STATUS_BLOCK IoStatus; 00396 PCMHIVE CmHive; 00397 HANDLE FileHandle; 00398 ULONG LengthToRead; 00399 HANDLE eventHandle = NULL; 00400 PKEVENT eventObject = NULL; 00401 00402 ASSERT(FIELD_OFFSET(CMHIVE, Hive) == 0); 00403 CmHive = (PCMHIVE)Hive; 00404 FileHandle = CmHive->FileHandles[FileType]; 00405 if (FileHandle == NULL) { 00406 return TRUE; 00407 } 00408 00409 CMLOG(CML_MAJOR, CMS_IO) { 00410 KdPrint(("CmpFileRead:\n")); 00411 KdPrint(("\tHandle=%08lx Offset=%08lx ", FileHandle, *FileOffset)); 00412 KdPrint(("Buffer=%08lx Length=%08lx\n", DataBuffer, DataLength)); 00413 } 00414 00415 // 00416 // Detect attempt to read off end of 2gig file (this should be irrelevent) 00417 // 00418 if ((0xffffffff - *FileOffset) < DataLength) { 00419 CMLOG(CML_MAJOR, CMS_IO_ERROR) KdPrint(("CmpFileRead: runoff\n")); 00420 return FALSE; 00421 } 00422 00423 status = CmpCreateEvent( 00424 SynchronizationEvent, 00425 &eventHandle, 00426 &eventObject); 00427 if (!NT_SUCCESS(status)) 00428 return FALSE; 00429 00430 // 00431 // We'd really like to just call the filesystems and have them do 00432 // the right thing. But the filesystem will attempt to lock our 00433 // entire buffer into memory, and that may fail for large requests. 00434 // So we split our reads into 64k chunks and call the filesystem for 00435 // each one. 00436 // 00437 ASSERT_PASSIVE_LEVEL(); 00438 while (DataLength > 0) { 00439 00440 // 00441 // Convert ULONG to Large 00442 // 00443 Offset.LowPart = *FileOffset; 00444 Offset.HighPart = 0L; 00445 00446 // 00447 // trim request down if necessary. 00448 // 00449 if (DataLength > MAX_FILE_IO) { 00450 LengthToRead = MAX_FILE_IO; 00451 } else { 00452 LengthToRead = DataLength; 00453 } 00454 00455 status = ZwReadFile( 00456 FileHandle, 00457 eventHandle, 00458 NULL, // apcroutine 00459 NULL, // apccontext 00460 &IoStatus, 00461 DataBuffer, 00462 LengthToRead, 00463 &Offset, 00464 NULL // key 00465 ); 00466 00467 if (STATUS_PENDING == status) { 00468 status = KeWaitForSingleObject(eventObject, Executive, 00469 KernelMode, FALSE, NULL); 00470 ASSERT(STATUS_SUCCESS == status); 00471 status = IoStatus.Status; 00472 } 00473 00474 // 00475 // adjust offsets 00476 // 00477 *FileOffset = Offset.LowPart + LengthToRead; 00478 DataLength -= LengthToRead; 00479 (PUCHAR)DataBuffer += LengthToRead; 00480 00481 if (NT_SUCCESS(status)) { 00482 ASSERT(IoStatus.Status == status); 00483 if (IoStatus.Information != LengthToRead) { 00484 CMLOG(CML_MAJOR, CMS_IO_ERROR) { 00485 KdPrint(("CmpFileRead:\n\t")); 00486 KdPrint(("Failure1: status = %08lx ", status)); 00487 KdPrint(("IoInformation = %08lx\n", IoStatus.Information)); 00488 } 00489 ObDereferenceObject(eventObject); 00490 ZwClose(eventHandle); 00491 return FALSE; 00492 } 00493 } else { 00494 // 00495 // set debugging info 00496 // 00497 CmRegistryIODebug.Action = CmpIoFileRead; 00498 CmRegistryIODebug.Handle = FileHandle; 00499 CmRegistryIODebug.Status = status; 00500 DbgPrint("CmpFileRead:\tFailure2: status = %08lx IoStatus = %08lx\n", status, IoStatus.Status); 00501 00502 ObDereferenceObject(eventObject); 00503 ZwClose(eventHandle); 00504 return FALSE; 00505 } 00506 00507 } 00508 ObDereferenceObject(eventObject); 00509 ZwClose(eventHandle); 00510 return TRUE; 00511 }

BOOLEAN CmpFileWrite PHHIVE  Hive,
ULONG  FileType,
PCMP_OFFSET_ARRAY  offsetArray,
ULONG  offsetArrayCount,
PULONG  FileOffset
 

Definition at line 516 of file cmwrapr.c.

References ASSERT, ASSERT_PASSIVE_LEVEL, CML_MAJOR, CMLOG, CmpCreateEvent(), CmpIoFileWrite, CmpNoWrite, CmRegistryIODebug, CMS_IO, CMS_IO_ERROR, DbgPrint, Executive, FALSE, _CMHIVE::FileHandles, Hive, KernelMode, KeWaitForMultipleObjects(), L, MAX_FILE_IO, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, Offset, PAGE_SIZE, perftouchbuffer, Status, and TRUE.

Referenced by CmpInitializeHive(), and CmpSaveKeyByFileCopy().

00525 : 00526 00527 This routine writes an array of buffers out to a file. 00528 00529 It is environment specific. 00530 00531 NOTE: We assume the handle is opened for asynchronous access, 00532 and that we, and not the IO system, are keeping the 00533 offset pointer. 00534 00535 NOTE: Only 32bit offsets are supported, even though the underlying 00536 IO system on NT supports 64 bit offsets. 00537 00538 Arguments: 00539 00540 Hive - Hive we are doing I/O for 00541 00542 FileType - which supporting file to use 00543 00544 offsetArray - array of structures where each structure holds a 32bit offset 00545 into the Hive file and pointer the a buffer written to that 00546 file offset. 00547 00548 offsetArrayCount - number of elements in the offsetArray. 00549 00550 FileOffset - returns the file offset after the last write to the file. 00551 00552 Return Value: 00553 00554 FALSE if failure 00555 TRUE if success 00556 00557 --*/ 00558 { 00559 NTSTATUS status; 00560 LARGE_INTEGER Offset; 00561 PCMHIVE CmHive; 00562 HANDLE FileHandle; 00563 ULONG LengthToWrite; 00564 LONG WaitBufferCount = 0; 00565 LONG idx; 00566 ULONG arrayCount = 0; 00567 PVOID DataBuffer; 00568 ULONG DataLength; 00569 HANDLE eventHandles[MAXIMUM_WAIT_OBJECTS]; 00570 PKEVENT eventObjects[MAXIMUM_WAIT_OBJECTS]; 00571 KWAIT_BLOCK waitBlockArray[MAXIMUM_WAIT_OBJECTS]; 00572 IO_STATUS_BLOCK IoStatus[MAXIMUM_WAIT_OBJECTS]; 00573 BOOLEAN ret_val = TRUE; 00574 00575 if (CmpNoWrite) { 00576 return TRUE; 00577 } 00578 00579 ASSERT(FIELD_OFFSET(CMHIVE, Hive) == 0); 00580 CmHive = (PCMHIVE)Hive; 00581 FileHandle = CmHive->FileHandles[FileType]; 00582 if (FileHandle == NULL) { 00583 return TRUE; 00584 } 00585 00586 CMLOG(CML_MAJOR, CMS_IO) { 00587 KdPrint(("CmpFileWrite:\n")); 00588 KdPrint(("\tHandle=%08lx ", FileHandle)); 00589 } 00590 00591 for (idx = 0; idx < MAXIMUM_WAIT_OBJECTS; idx++) { 00592 eventHandles[idx] = NULL; 00593 } 00594 00595 // Bring pages being written into memory first to allow disk to write 00596 // buffer contiguously. 00597 for (idx = 0; (ULONG) idx < offsetArrayCount; idx++) { 00598 char * start = offsetArray[idx].DataBuffer; 00599 char * end = (char *) start + offsetArray[idx].DataLength; 00600 while (start < end) { 00601 // perftouchbuffer globally declared so that compiler won't try 00602 // to remove it and this loop (if its smart enough?). 00603 perftouchbuffer += (ULONG) *start; 00604 start += PAGE_SIZE; 00605 } 00606 } 00607 00608 // 00609 // We'd really like to just call the filesystems and have them do 00610 // the right thing. But the filesystem will attempt to lock our 00611 // entire buffer into memory, and that may fail for large requests. 00612 // So we split our reads into 64k chunks and call the filesystem for 00613 // each one. 00614 // 00615 ASSERT_PASSIVE_LEVEL(); 00616 arrayCount = 0; 00617 DataLength = 0; 00618 // This outer loop is hit more than once if the MAXIMUM_WAIT_OBJECTS limit 00619 // is hit before the offset array is drained. 00620 while (arrayCount < offsetArrayCount) { 00621 WaitBufferCount = 0; 00622 00623 // This loop fills the wait buffer. 00624 while ((arrayCount < offsetArrayCount) && 00625 (WaitBufferCount < MAXIMUM_WAIT_OBJECTS)) { 00626 00627 // If data length isn't zero than the wait buffer filled before the 00628 // buffer in the last offsetArray element was sent to write file. 00629 if (DataLength == 0) { 00630 *FileOffset = offsetArray[arrayCount].FileOffset; 00631 DataBuffer = offsetArray[arrayCount].DataBuffer; 00632 DataLength = offsetArray[arrayCount].DataLength; 00633 // 00634 // Detect attempt to read off end of 2gig file 00635 // (this should be irrelevent) 00636 // 00637 if ((0xffffffff - *FileOffset) < DataLength) { 00638 CMLOG(CML_MAJOR, CMS_IO_ERROR) KdPrint(("CmpFileWrite: runoff\n")); 00639 goto Error_Exit; 00640 } 00641 } 00642 // else still more to write out of last buffer. 00643 00644 while ((DataLength > 0) && (WaitBufferCount < MAXIMUM_WAIT_OBJECTS)) { 00645 00646 // 00647 // Convert ULONG to Large 00648 // 00649 Offset.LowPart = *FileOffset; 00650 Offset.HighPart = 0L; 00651 00652 // 00653 // trim request down if necessary. 00654 // 00655 if (DataLength > MAX_FILE_IO) { 00656 LengthToWrite = MAX_FILE_IO; 00657 } else { 00658 LengthToWrite = DataLength; 00659 } 00660 00661 // Previously created events are reused. 00662 if (eventHandles[WaitBufferCount] == NULL) { 00663 status = CmpCreateEvent(SynchronizationEvent, 00664 &eventHandles[WaitBufferCount], 00665 &eventObjects[WaitBufferCount]); 00666 if (!NT_SUCCESS(status)) { 00667 // Make sure we don't try to clean this up. 00668 eventHandles[WaitBufferCount] = NULL; 00669 goto Error_Exit; 00670 } 00671 } 00672 00673 status = ZwWriteFile(FileHandle, 00674 eventHandles[WaitBufferCount], 00675 NULL, // apcroutine 00676 NULL, // apccontext 00677 &IoStatus[WaitBufferCount], 00678 DataBuffer, 00679 LengthToWrite, 00680 &Offset, 00681 NULL); 00682 00683 if (!NT_SUCCESS(status)) { 00684 goto Error_Exit; 00685 } 00686 00687 WaitBufferCount++; 00688 00689 // 00690 // adjust offsets 00691 // 00692 *FileOffset = Offset.LowPart + LengthToWrite; 00693 DataLength -= LengthToWrite; 00694 (PUCHAR)DataBuffer += LengthToWrite; 00695 } // while (DataLength > 0 && WaitBufferCount < MAXIMUM_WAIT_OBJECTS) 00696 00697 arrayCount++; 00698 00699 } // while (arrayCount < offsetArrayCount && 00700 // WaitBufferCount < MAXIMUM_WAIT_OBJECTS) 00701 00702 status = KeWaitForMultipleObjects(WaitBufferCount, 00703 eventObjects, 00704 WaitAll, 00705 Executive, 00706 KernelMode, 00707 FALSE, 00708 NULL, 00709 waitBlockArray); 00710 00711 if (!NT_SUCCESS(status)) 00712 goto Error_Exit; 00713 00714 for (idx = 0; idx < WaitBufferCount; idx++) { 00715 if (!NT_SUCCESS(IoStatus[idx].Status)) { 00716 ret_val = FALSE; 00717 goto Done; 00718 } 00719 } 00720 00721 // There may still be more to do if the last element held a big buffer 00722 // and the wait buffer filled before it was all sent to the file. 00723 if (DataLength > 0) { 00724 arrayCount--; 00725 } 00726 00727 } // while (arrayCount < offsetArrayCount) 00728 00729 ret_val = TRUE; 00730 00731 goto Done; 00732 Error_Exit: 00733 // 00734 // set debugging info 00735 // 00736 CmRegistryIODebug.Action = CmpIoFileWrite; 00737 CmRegistryIODebug.Handle = FileHandle; 00738 CmRegistryIODebug.Status = status; 00739 DbgPrint("CmpFileWrite: error exiting %d\n", status); 00740 // 00741 // if WaitBufferCount > 0 then we have successfully issued 00742 // some I/Os, but not all of them. This is an error, but we 00743 // cannot return from this routine until all the successfully 00744 // issued I/Os have completed. 00745 // 00746 if (WaitBufferCount > 0) { 00747 status = KeWaitForMultipleObjects(WaitBufferCount, 00748 eventObjects, 00749 WaitAll, 00750 Executive, 00751 KernelMode, 00752 FALSE, 00753 NULL, 00754 waitBlockArray); 00755 } 00756 00757 00758 ret_val = FALSE; 00759 Done: 00760 idx = 0; 00761 // Clean up open event handles and objects. 00762 while ((idx < MAXIMUM_WAIT_OBJECTS) && (eventHandles[idx] != NULL)) { 00763 ObDereferenceObject(eventObjects[idx]); 00764 ZwClose(eventHandles[idx]); 00765 idx++; 00766 } 00767 return ret_val; 00768 }

VOID CmpFree PVOID  MemoryBlock,
ULONG  GlobalQuotaSize
 

Definition at line 186 of file cmwrapr.c.

References ASSERT, CML_MINOR, CMLOG, CmpReleaseGlobalQuota(), CMS_POOL, ExFreePool(), and RtlGetCallersAddress().

Referenced by CmpDestroyTemporaryHive(), CmpInitializeHive(), CmpValidateAlternate(), CmReplaceKey(), CmUnloadKey(), EhCloseHive(), HvFreeHive(), HvFreeHivePartial(), and HvWriteHive().

00192 : 00193 00194 This routine frees memory that has been allocated by the registry. 00195 00196 It is environment specific 00197 00198 00199 Arguments: 00200 00201 MemoryBlock - supplies address of memory object to free 00202 00203 GlobalQuotaSize - amount of global quota to release 00204 00205 Return Value: 00206 00207 NONE 00208 00209 --*/ 00210 { 00211 #if DBG 00212 PVOID Caller; 00213 PVOID CallerCaller; 00214 RtlGetCallersAddress(&Caller, &CallerCaller); 00215 CMLOG(CML_MINOR, CMS_POOL) { 00216 KdPrint(("**FREEING:%08lx c,cc:%08lx,%08lx\n", MemoryBlock, Caller, CallerCaller)); 00217 } 00218 #endif 00219 ASSERT(GlobalQuotaSize > 0); 00220 CmpReleaseGlobalQuota(GlobalQuotaSize); 00221 ExFreePool(MemoryBlock); 00222 return; 00223 }


Variable Documentation

ULONG Action
 

Definition at line 52 of file cmwrapr.c.

BOOLEAN CmpNoWrite
 

Definition at line 38 of file cmwrapr.c.

struct { ... } CmRegistryIODebug
 

HANDLE Handle
 

Definition at line 53 of file cmwrapr.c.

ULONG perftouchbuffer = 0
 

Definition at line 24 of file cmwrapr.c.

Referenced by CmpFileWrite().

NTSTATUS Status
 

Definition at line 54 of file cmwrapr.c.


Generated on Sat May 15 19:43:12 2004 for test by doxygen 1.3.7