test: super.c Source File

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 }