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

super.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1992 Microsoft Corporation 00004 00005 Module Name: 00006 00007 super.c 00008 00009 Abstract: 00010 00011 This module contains the routines which implement the SuperSection 00012 object. 00013 00014 Author: 00015 00016 Lou Perazzoli (loup) 4-Apr-92 00017 00018 Revision History: 00019 00020 --*/ 00021 00022 #include "mi.h" 00023 #include "zwapi.h" 00024 00025 00026 VOID 00027 MiSuperSectionDelete ( 00028 PVOID Object 00029 ); 00030 00031 BOOLEAN 00032 MiSuperSectionInitialization ( 00033 ); 00034 00035 #ifdef ALLOC_PRAGMA 00036 #pragma alloc_text(INIT,MiSuperSectionInitialization) 00037 #endif 00038 00039 #define MM_MAX_SUPERSECTION_COUNT (32) 00040 00041 POBJECT_TYPE MmSuperSectionObjectType; 00042 00043 #define STATUS_TOO_MANY_SECTIONS ((NTSTATUS)0xC0033333) 00044 #define STATUS_INCOMPLETE_MAP ((NTSTATUS)0xC0033334) 00045 00046 00047 extern GENERIC_MAPPING MiSectionMapping; 00048 00049 typedef struct _MMSUPER_SECTION { 00050 ULONG NumberOfSections; 00051 PSECTION SectionPointers[1]; 00052 } MMSUPER_SECTION, *PMMSUPER_SECTION; 00053 00054 00055 NTSTATUS 00056 NtCreateSuperSection ( 00057 OUT PHANDLE SuperSectionHandle, 00058 IN ACCESS_MASK DesiredAccess, 00059 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 00060 IN ULONG Count, 00061 IN HANDLE SectionHandles[] 00062 ) 00063 00064 /*++ 00065 00066 Routine Description: 00067 00068 This routine creates a super section object. A supersection 00069 object consists a group of sections that are mapped as images. 00070 00071 Arguments: 00072 00073 SuperSectionHandle - Returns a handle to the created supersection. 00074 00075 DesiredAccess - Supplies the desired access for the super section. 00076 00077 ObjectAttributes - Supplies the object attributes for the super 00078 section. 00079 00080 Count - Supplies the number of sections contained in the section 00081 handle array. 00082 00083 SectionHandles[] - Supplies the section handles to place into 00084 the supersection. 00085 00086 00087 Return Value: 00088 00089 Returns the status 00090 00091 TBS 00092 00093 --*/ 00094 00095 { 00096 NTSTATUS Status; 00097 PSECTION Section; 00098 PCONTROL_AREA ControlArea; 00099 HANDLE CapturedHandle; 00100 HANDLE CapturedHandles[MM_MAX_SUPERSECTION_COUNT]; 00101 PMMSUPER_SECTION SuperSection; 00102 KPROCESSOR_MODE PreviousMode; 00103 ULONG RefCount; 00104 ULONG i; 00105 KIRQL OldIrql; 00106 00107 if (Count > MM_MAX_SUPERSECTION_COUNT) { 00108 return STATUS_TOO_MANY_SECTIONS; 00109 } 00110 00111 try { 00112 00113 if (PreviousMode != KernelMode) { 00114 ProbeForWriteHandle (SuperSectionHandle); 00115 } 00116 00117 i= 0; 00118 do { 00119 CapturedHandles[i] = SectionHandles[i]; 00120 i += 1; 00121 } while (i < Count); 00122 00123 } except (ExSystemExceptionFilter()) { 00124 00125 // 00126 // If an exception occurs during the probe or capture 00127 // of the initial values, then handle the exception and 00128 // return the exception code as the status value. 00129 // 00130 00131 return GetExceptionCode(); 00132 } 00133 00134 Status = ObCreateObject (PreviousMode, 00135 MmSuperSectionObjectType, 00136 ObjectAttributes, 00137 PreviousMode, 00138 NULL, 00139 sizeof(MMSUPER_SECTION) + 00140 (sizeof(PSECTION) * (Count - 1)), 00141 sizeof(MMSUPER_SECTION) + 00142 (sizeof(PSECTION) * (Count - 1)), 00143 0, 00144 (PVOID *)&SuperSection); 00145 00146 if (!NT_SUCCESS(Status)) { 00147 return Status; 00148 } 00149 00150 SuperSection->NumberOfSections = Count; 00151 00152 i = 0; 00153 RefCount = 0; 00154 do { 00155 00156 // 00157 // Get a referenced pointer to the specified objects with 00158 // the desired access. 00159 // 00160 00161 Status = ObReferenceObjectByHandle(CapturedHandles[i], 00162 DesiredAccess, 00163 MmSectionObjectType, 00164 PreviousMode, 00165 (PVOID *)&Section, 00166 NULL); 00167 00168 if (NT_SUCCESS(Status) != FALSE) { 00169 if (Section->u.Flags.Image == 0) { 00170 00171 // 00172 // This is not an image section, return an error. 00173 // 00174 00175 Status = STATUS_SECTION_NOT_IMAGE; 00176 goto ServiceFailed; 00177 } 00178 RefCount += 1; 00179 SuperSection->SectionPointers[i] = Section; 00180 } else { 00181 goto ServiceFailed; 00182 } 00183 00184 i += 1; 00185 } while (i < Count); 00186 00187 i= 0; 00188 do { 00189 00190 // 00191 // For each section increment the number of section references 00192 // count. 00193 // 00194 00195 ControlArea = SuperSection->SectionPointers[i]->Segment->ControlArea; 00196 00197 LOCK_PFN (OldIrql); 00198 ControlArea->NumberOfSectionReferences += 1; 00199 ControlArea->NumberOfUserReferences += 1; 00200 UNLOCK_PFN (OldIrql); 00201 i++; 00202 00203 } while (i < Count); 00204 00205 00206 Status = ObInsertObject (SuperSection, 00207 NULL, 00208 DesiredAccess, 00209 0, 00210 (PVOID *)NULL, 00211 &CapturedHandle); 00212 00213 try { 00214 *SuperSectionHandle = CapturedHandle; 00215 } except (EXCEPTION_EXECUTE_HANDLER) { 00216 return Status; 00217 } 00218 return Status; 00219 00220 ServiceFailed: 00221 while (RefCount > 0) { 00222 RefCount -= 1; 00223 ObDereferenceObject(SuperSection->SectionPointers[RefCount]); 00224 } 00225 00226 // 00227 // Delete the supersection object as it was never inserted into 00228 // a handle table. 00229 // 00230 00231 ObDereferenceObject (SuperSection); 00232 return Status; 00233 } 00234 00235 00236 NTSTATUS 00237 NtOpenSuperSection ( 00238 OUT PHANDLE SuperSectionHandle, 00239 IN ACCESS_MASK DesiredAccess, 00240 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 00241 ) 00242 00243 /*++ 00244 00245 Routine Description: 00246 00247 This routine opens a super section object. A supersection 00248 object consists a group of sections that are mapped as images. 00249 00250 Arguments: 00251 00252 SuperSectionHandle - Returns a handle to the created supersection. 00253 00254 DesiredAccess - Supplies the desired access for the super section. 00255 00256 ObjectAttributes - Supplies the object attributes for the super 00257 section. 00258 00259 00260 Return Value: 00261 00262 Returns the status 00263 00264 TBS 00265 00266 --*/ 00267 00268 { 00269 HANDLE Handle; 00270 KPROCESSOR_MODE PreviousMode; 00271 NTSTATUS Status; 00272 00273 // 00274 // Get previous processor mode and probe output arguments if necessary. 00275 // 00276 00277 PreviousMode = KeGetPreviousMode(); 00278 if (PreviousMode != KernelMode) { 00279 try { 00280 ProbeForWriteHandle(SuperSectionHandle); 00281 } except (EXCEPTION_EXECUTE_HANDLER) { 00282 return GetExceptionCode(); 00283 } 00284 } 00285 00286 // 00287 // Open handle to the super section object with the specified desired 00288 // access. 00289 // 00290 00291 Status = ObOpenObjectByName (ObjectAttributes, 00292 MmSuperSectionObjectType, 00293 PreviousMode, 00294 NULL, 00295 DesiredAccess, 00296 NULL, 00297 &Handle 00298 ); 00299 00300 try { 00301 *SuperSectionHandle = Handle; 00302 } except (EXCEPTION_EXECUTE_HANDLER) { 00303 return Status; 00304 } 00305 00306 return Status; 00307 } 00308 00309 00310 NTSTATUS 00311 NtMapViewOfSuperSection ( 00312 IN HANDLE SuperSectionHandle, 00313 IN HANDLE ProcessHandle, 00314 IN OUT PULONG Count, 00315 OUT PVOID BaseAddress[], 00316 OUT ULONG ViewSize[], 00317 IN SECTION_INHERIT InheritDisposition, 00318 ) 00319 00320 /*++ 00321 00322 Routine Description: 00323 00324 This routine maps into the specified process a view of each 00325 section contained within the supersection. 00326 00327 Arguments: 00328 00329 SuperSectionHandle - Supplies a handle to the supersection. 00330 00331 ProcessHandle - Supplies a handle to the process in which to 00332 map the supersection's sections. 00333 00334 Count - Supplies the number of elements in the BaseAddress and 00335 ViewSize arrays, returns the number of views actually 00336 mapped. 00337 00338 00339 BaseAddresses[] - Returns the base address of each view that was mapped. 00340 00341 ViewSize[] - Returns the view size of each view that was mapped. 00342 00343 InheritDisposition - Supplies the inherit disposition to be applied 00344 to each section which is contained in the 00345 super section. 00346 00347 Return Value: 00348 00349 Returns the status 00350 00351 TBS 00352 00353 --*/ 00354 00355 { 00356 NTSTATUS Status; 00357 PVOID CapturedBases[MM_MAX_SUPERSECTION_COUNT]; 00358 ULONG CapturedViews[MM_MAX_SUPERSECTION_COUNT]; 00359 PMMSUPER_SECTION SuperSection; 00360 KPROCESSOR_MODE PreviousMode; 00361 ULONG i; 00362 ULONG CapturedCount; 00363 ULONG NumberMapped; 00364 PEPROCESS Process; 00365 LARGE_INTEGER LargeZero = {0,0}; 00366 00367 00368 PreviousMode = KeGetPreviousMode(); 00369 00370 try { 00371 ProbeForWriteUlong (Count); 00372 CapturedCount = *Count; 00373 00374 if (PreviousMode != KernelMode) { 00375 ProbeForWrite (BaseAddress, 00376 sizeof(PVOID) * CapturedCount, 00377 sizeof(PVOID)); 00378 ProbeForWrite (ViewSize, 00379 sizeof(ULONG) * CapturedCount, 00380 sizeof(ULONG)); 00381 } 00382 00383 } except (ExSystemExceptionFilter()) { 00384 00385 // 00386 // If an exception occurs during the probe or capture 00387 // of the initial values, then handle the exception and 00388 // return the exception code as the status value. 00389 // 00390 00391 return GetExceptionCode(); 00392 } 00393 00394 Status = ObReferenceObjectByHandle ( ProcessHandle, 00395 PROCESS_VM_OPERATION, 00396 PsProcessType, 00397 PreviousMode, 00398 (PVOID *)&Process, 00399 NULL ); 00400 if (!NT_SUCCESS(Status)) { 00401 return Status; 00402 } 00403 00404 // 00405 // Reference the supersection object. 00406 // 00407 00408 Status = ObReferenceObjectByHandle ( SuperSectionHandle, 00409 SECTION_MAP_EXECUTE, 00410 MmSuperSectionObjectType, 00411 PreviousMode, 00412 (PVOID *)&SuperSection, 00413 NULL ); 00414 00415 if (!NT_SUCCESS(Status)) { 00416 ObDereferenceObject (Process); 00417 return Status; 00418 } 00419 00420 if (CapturedCount < SuperSection->NumberOfSections) { 00421 ObDereferenceObject (Process); 00422 ObDereferenceObject (SuperSection); 00423 return STATUS_BUFFER_TOO_SMALL; 00424 } 00425 00426 NumberMapped = 0; 00427 do { 00428 00429 // 00430 // For each section within the supersection, map a view in 00431 // the specified process. 00432 // 00433 00434 Status = MmMapViewOfSection (SuperSection->SectionPointers[i], 00435 Process, 00436 &CapturedBases[i], 00437 0, 00438 0, 00439 &LargeZero, 00440 &CapturedViews[i], 00441 InheritDisposition, 00442 0, 00443 PAGE_EXECUTE); 00444 00445 if (NT_SUCCESS (Status) == FALSE) { 00446 Status = STATUS_INCOMPLETE_MAP; 00447 break; 00448 } 00449 NumberMapped++; 00450 } while (NumberMapped < SuperSection->NumberOfSections); 00451 00452 // 00453 // Dereference the supersection and the process. 00454 // 00455 00456 ObDereferenceObject (SuperSection); 00457 ObDereferenceObject (Process); 00458 00459 try { 00460 *Count = NumberMapped; 00461 i = 0; 00462 00463 do { 00464 00465 // 00466 // Store the captured view base and sizes for each section 00467 // that was mapped. 00468 // 00469 00470 BaseAddress[i] = CapturedBases[i]; 00471 ViewSize[i] = CapturedViews[i]; 00472 00473 i++; 00474 } while (i < NumberMapped); 00475 00476 } except (ExSystemExceptionFilter()) { 00477 NOTHING; 00478 } 00479 00480 return(Status); 00481 } 00482 00483 00484 00485 #if 0 00486 00487 NTSTATUS 00488 NtQuerySuperSection ( 00489 IN HANDLE SuperSectionHandle, 00490 IN SUPERSECTION_INFORMATION_CLASS SectionInformationClass, 00491 OUT PVOID SuperSectionInformation, 00492 IN ULONG SuperSectionInformationLength, 00493 OUT PULONG ReturnLength OPTIONAL 00494 ) 00495 00496 Routine Description: 00497 00498 This function returns information about an opened supersection object. 00499 This function provides the capability to determine the basic section 00500 information about each section in the supersection or the image 00501 information about each section in the supersection. 00502 00503 Arguments: 00504 00505 SuperSectionHandle - Supplies an open handle to a section object. 00506 00507 SectionInformationClass - The section information class about 00508 which to retrieve information. 00509 00510 SuperSectionInformation - A pointer to a buffer that receives the 00511 specified information. The format and content of the buffer 00512 depend on the specified section class. 00513 00514 00515 SuperSectionInformationLength - Specifies the length in bytes of the 00516 section information buffer. 00517 00518 ReturnLength - An optional pointer which, if specified, receives 00519 the number of bytes placed in the section information buffer. 00520 00521 00522 Return Value: 00523 00524 Returns the status 00525 00526 TBS 00527 00528 00529 --*/ 00530 00531 00532 #endif //0 00533 00534 VOID 00535 MiSuperSectionDelete ( 00536 PVOID Object 00537 ) 00538 00539 /*++ 00540 00541 Routine Description: 00542 00543 00544 This routine is called by the object management procedures whenever 00545 the last reference to a super section object has been removed. 00546 This routine dereferences the associated segment objects. 00547 00548 Arguments: 00549 00550 Object - a pointer to the body of the supersection object. 00551 00552 Return Value: 00553 00554 None. 00555 00556 --*/ 00557 00558 { 00559 PMMSUPER_SECTION SuperSection; 00560 PCONTROL_AREA ControlArea; 00561 KIRQL OldIrql; 00562 ULONG i = 0; 00563 00564 SuperSection = (PMMSUPER_SECTION)Object; 00565 00566 do { 00567 00568 // 00569 // For each section increment the number of section references 00570 // count. 00571 // 00572 00573 ControlArea = SuperSection->SectionPointers[i]->Segment->ControlArea; 00574 00575 LOCK_PFN (OldIrql); 00576 ControlArea->NumberOfSectionReferences -= 1; 00577 ControlArea->NumberOfUserReferences -= 1; 00578 UNLOCK_PFN (OldIrql); 00579 ObDereferenceObject (SuperSection->SectionPointers[i]); 00580 i++; 00581 00582 } while (i < SuperSection->NumberOfSections); 00583 00584 return; 00585 } 00586 00587 BOOLEAN 00588 MiSuperSectionInitialization ( 00589 ) 00590 00591 /*++ 00592 00593 Routine Description: 00594 00595 This function creates the section object type descriptor at system 00596 initialization and stores the address of the object type descriptor 00597 in global storage. 00598 00599 Arguments: 00600 00601 None. 00602 00603 Return Value: 00604 00605 TRUE - Initialization was successful. 00606 00607 FALSE - Initialization Failed. 00608 00609 00610 00611 --*/ 00612 00613 { 00614 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; 00615 UNICODE_STRING TypeName; 00616 00617 // 00618 // Initialize the common fields of the Object Type Initializer record 00619 // 00620 00621 RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) ); 00622 ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer ); 00623 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; 00624 ObjectTypeInitializer.GenericMapping = MiSectionMapping; 00625 ObjectTypeInitializer.PoolType = PagedPool; 00626 00627 // 00628 // Initialize string descriptor. 00629 // 00630 00631 RtlInitUnicodeString (&TypeName, L"SuperSection"); 00632 00633 // 00634 // Create the section object type descriptor 00635 // 00636 00637 ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS; 00638 ObjectTypeInitializer.DeleteProcedure = MiSuperSectionDelete; 00639 ObjectTypeInitializer.GenericMapping = MiSectionMapping; 00640 ObjectTypeInitializer.UseDefaultObject = TRUE; 00641 if ( !NT_SUCCESS(ObCreateObjectType(&TypeName, 00642 &ObjectTypeInitializer, 00643 (PSECURITY_DESCRIPTOR) NULL, 00644 &MmSuperSectionObjectType 00645 )) ) { 00646 return FALSE; 00647 } 00648 00649 return TRUE; 00650 00651 }

Generated on Sat May 15 19:41:54 2004 for test by doxygen 1.3.7