test: restrfil.c File Reference

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

# restrfil.c File Reference

`#include <nt.h>`
`#include <ntdef.h>`
`#include <ntrtl.h>`
`#include <nturtl.h>`
`#include <windef.h>`
`#include <winbase.h>`

Go to the source code of this file.

## Defines

#define | GetSiteSidFromToken xxxGetSiteSidFromToken
#define | GetMangledSiteSid xxxGetMangledSiteSid
#define | IsTokenRestricted xxxIsTokenRestricted
#define | CALL_CREATE(object)
#define | CALL_OPEN(object)

## Enumerations

enum | { eUnRestricted = 0, eRestricted, eUnknownRestricted }

## Functions

void | Base32Encode (LPVOID pvData, UINT cbData, LPWSTR pchData)
HRESULT | GetMangledSiteSid (PSID pSid, ULONG cchMangledSite, LPWSTR *ppwszMangledSite)
PSID | GetSiteSidFromToken (IN HANDLE TokenHandle)
BOOL | IsTokenRestricted (IN HANDLE TokenHandle)
BOOL | IsInterestingPath (OBJECT_ATTRIBUTES *NormalFile, OBJECT_ATTRIBUTES *RestrictedFile)
NTSTATUS | CopyRestrictedFile (OBJECT_ATTRIBUTES *SourceAttributes, OBJECT_ATTRIBUTES *DestinationAttributes)
NTSTATUS | CreateDirectories (OBJECT_ATTRIBUTES *Attributes)
BOOL | FileExists (OBJECT_ATTRIBUTES *Attributes)
NTSTATUS | CopyStream (HANDLE SourceFile, HANDLE DestinationFile, FILE_STREAM_INFORMATION *StreamInfo, BYTE *Buffer, ULONG BufferSize)
NTSTATUS | InitializeRestrictedStuff ()
NTSTATUS | NtUnRestrictedCreateFile (OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength)
NTSTATUS | NtUnRestrictedOpenFile (OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG ShareAccess, IN ULONG OpenOptions)
NTSTATUS | NtUnRestrictedDeleteFile (IN POBJECT_ATTRIBUTES ObjectAttributes)
NTSTATUS | NtUnRestrictedQueryAttributesFile (IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_BASIC_INFORMATION FileInformation)
NTSTATUS | NtUnRestrictedSetInformationFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass)
void | CheckRestricted ()
__inline BOOL | IsRestricted ()
NTSTATUS | NtCreateFile (OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength)
NTSTATUS | ZwCreateFile (OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength)
NTSTATUS | NtOpenFile (OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG ShareAccess, IN ULONG OpenOptions)
NTSTATUS | ZwOpenFile (OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG ShareAccess, IN ULONG OpenOptions)
NTSTATUS | NtDeleteFile (IN POBJECT_ATTRIBUTES ObjectAttributes)
NTSTATUS | ZwDeleteFile (IN POBJECT_ATTRIBUTES ObjectAttributes)
NTSTATUS | NtQueryAttributesFile (IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_BASIC_INFORMATION FileInformation)
NTSTATUS | ZwQueryAttributesFile (IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_BASIC_INFORMATION FileInformation)
NTSTATUS | NtSetInformationFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass)
NTSTATUS | ZwSetInformationFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass)
BOOL | IsInterestingPath (IN POBJECT_ATTRIBUTES NormalFile, IN OUT POBJECT_ATTRIBUTES RestrictedFile)

## Variables

enum { ... } | Restricted
UNICODE_STRING | SystemPath1 = {0, 0, 0}
UNICODE_STRING | SystemPath2 = {0, 0, 0}
UNICODE_STRING | SystemPath3 = {0, 0, 0}
UNICODE_STRING | SiteDirectory = {0, 0, 0}

## Define Documentation

#define CALL_CREATE | ( | object |  | ) |

Value:

    NtUnRestrictedCreateFile(       \
                        FileHandle,             \
                        DesiredAccess,          \
                        object,                 \
                        IoStatusBlock,          \
                        AllocationSize,         \
                        FileAttributes,         \
                        ShareAccess,            \
                        CreateDisposition,      \
                        CreateOptions,          \
                        EaBuffer,               \
                        EaLength)

Referenced by NtCreateFile().

#define CALL_OPEN | ( | object |  | ) |

Value:

    NtUnRestrictedOpenFile(       \
                        FileHandle,             \
                        DesiredAccess,          \
                        object,                 \
                        IoStatusBlock,          \
                        ShareAccess,            \
                        OpenOptions)

Referenced by NtOpenFile().

#define GetMangledSiteSid xxxGetMangledSiteSid

| Definition at line 38 of file restrfil.c. Referenced by InitializeRestrictedStuff().

#define GetSiteSidFromToken xxxGetSiteSidFromToken

| Definition at line 37 of file restrfil.c. Referenced by InitializeRestrictedStuff().

#define IsTokenRestricted xxxIsTokenRestricted

| Definition at line 39 of file restrfil.c. Referenced by CheckRestricted().

## Enumeration Type Documentation

anonymous enum

Enumeration values:

  eUnRestricted |
  eRestricted |
  eUnknownRestricted |

Definition at line 113 of file restrfil.c.

    00114 {
    00115     eUnRestricted = 0,
    00116     eRestricted,
    00117     eUnknownRestricted
    00118 }

## Function Documentation

void Base32Encode | ( | LPVOID | pvData,
|  | UINT | cbData,
|  | LPWSTR | pchData
| ) |

Definition at line 1953 of file restrfil.c.

References BYTE, and L.

Referenced by GetMangledSiteSid().

    01954 {
    01955     static const WCHAR alphabet[32] =
    01956         { L'a', L'b', L'c', L'd', L'e', L'f', L'g', L'h',
    01957           L'i', L'j', L'k', L'l', L'm', L'n', L'o', L'p',
    01958           L'q', L'r', L's', L't', L'u', L'v', L'w', L'x',
    01959           L'y', L'z', L'0', L'1', L'2', L'3', L'4', L'5' };
    01960
    01961     int   shift = 0;    // The # of unprocessed bits in accum
    01962     ULONG accum = 0;    // The unprocessed bits
    01963     ULONG value;
    01964     BYTE *pData = (BYTE *) pvData;
    01965
    01966     // For each byte...
    01967
    01968     while (cbData)
    01969     {
    01970         // Move the byte into the low bits of the accumulator
    01971
    01972         accum = (accum << 8) | *pData++;
    01973         shift += 8;
    01974         --cbData;
    01975
    01976         // Lop off the high 5 or 10 bits and write them out
    01977
    01978         while ( shift >= 5 )
    01979         {
    01980             shift -= 5;
    01981             value = (accum >> shift) & 0x1Fl;
    01982
    01983             *pchData++ = alphabet[value];
    01984         }
    01985     }
    01986
    01987     // If there are any remaining bits, push out one more char padded with 0's
    01988
    01989     if (shift)
    01990     {
    01991         value = (accum << (5 - shift)) & 0x1Fl;
    01992
    01993         *pchData++ = alphabet[value];
    01994     }
    01995
    01996     *pchData = L'\0';
    01997 }

void CheckRestricted | ( |  | ) |

Definition at line 129 of file restrfil.c.

References Buffer, BYTE, DWORD, eRestricted, eUnRestricted, InitializeRestrictedStuff(), IsTokenRestricted, L, NT_SUCCESS, NtClose(), NtOpenKey(), NtOpenProcessToken(), NtQueryValueKey(), NTSTATUS(), NULL, Restricted, RtlInitUnicodeString(), and Status.

Referenced by IsRestricted().

    00132                    :
    00133
    00134     Determine if this is a restricted process and thus should have filesystem
    00135     redirection active.
    00136
    00137 Arguments:
    00138
    00139     None
    00140
    00141 Return Value:
    00142
    00143     void
    00144
    00145 --*/
    00146 {
    00147     NTSTATUS            Status;
    00148     HANDLE              hToken;
    00149     UNICODE_STRING      SandboxKeyName;
    00150     HANDLE              SandboxKey;
    00151     OBJECT_ATTRIBUTES   Attributes;
    00152     BYTE                Buffer[256];
    00153     ULONG               Length;
    00154
    00155     KEY_VALUE_PARTIAL_INFORMATION *ValueInfo = (KEY_VALUE_PARTIAL_INFORMATION *) Buffer;
    00156
    00157     //
    00158     // Assume unrestricted unless we have reason to believe otherwise
    00159     //
    00160
    00161     Restricted = eUnRestricted;
    00162
    00163     //
    00164     // HACKHACK: Temporarily allow redirection to be forced off by setting
    00165     //           HKLM\Software\Sandbox!FileSystemRedir = (REG_DWORD) 0
    00166     //
    00167
    00168     RtlInitUnicodeString(&SandboxKeyName, L"\\Registry\\Machine\\Software\\Sandbox");
    00169
    00170     InitializeObjectAttributes(
    00171             &Attributes,
    00172             &SandboxKeyName,
    00173             OBJ_CASE_INSENSITIVE,
    00174             NULL,
    00175             NULL);
    00176
    00177     Status = NtOpenKey(&SandboxKey, KEY_READ, &Attributes);
    00178
    00179     if (!NT_SUCCESS(Status) && STATUS_OBJECT_NAME_NOT_FOUND != Status)
    00180         return;
    00181
    00182     if (NT_SUCCESS(Status))
    00183     {
    00184         RtlInitUnicodeString(&SandboxKeyName, L"FileSystemRedir");
    00185
    00186         Status = NtQueryValueKey(
    00187                         SandboxKey,
    00188                         &SandboxKeyName,
    00189                         KeyValuePartialInformation,
    00190                         ValueInfo,
    00191                         sizeof(Buffer),
    00192                         &Length);
    00193
    00194         NtClose(SandboxKey);
    00195
    00196         if (!NT_SUCCESS(Status) && STATUS_OBJECT_NAME_NOT_FOUND != Status)
    00197             return;
    00198
    00199         if (NT_SUCCESS(Status) && 0 == * (DWORD *) (&ValueInfo->Data))
    00200             return;
    00201     }
    00202
    00203     Status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_READ, &hToken);
    00204
    00205     if (NT_SUCCESS(Status))
    00206     {
    00207         if (IsTokenRestricted(hToken))
    00208         {
    00209             Status = InitializeRestrictedStuff();
    00210
    00211             if (NT_SUCCESS(Status))
    00212                 Restricted = eRestricted;
    00213         }
    00214
    00215         NtClose(hToken);
    00216     }
    00217 }

NTSTATUS CopyRestrictedFile | ( | OBJECT_ATTRIBUTES * | SourceAttributes,
|  | OBJECT_ATTRIBUTES * | DestinationAttributes
| ) |

Definition at line 1596 of file restrfil.c.

References ASSERT, Buffer, BufferSize, BYTE, CopyStream(), CreateDirectories(), NT_SUCCESS, NtClose(), NtQueryInformationFile(), NtSetInformationFile(), NTSTATUS(), NtUnRestrictedCreateFile(), NtUnRestrictedDeleteFile(), NtUnRestrictedOpenFile(), NtUnRestrictedQueryAttributesFile(), NULL, RtlAllocateHeap, RtlFreeHeap, and Status.

Referenced by NtCreateFile(), and NtOpenFile().

    01601                    :
    01602
    01603     Copy a file.  Substreams in the file are copied and a best effort is made
    01604     to preserve the file attributes - although the copy does not fail if
    01605     the attributes can't be preserved.  Acl's and extended attributes such
    01606     as object id's are not copied.
    01607
    01608     If the any of the parent directories of the destination don't exist they
    01609     are created.
    01610
    01611 Arguments:
    01612
    01613     SourceAttributes        - The source file
    01614     DestinationAttributues  - The destination file
    01615
    01616 Return Value:
    01617
    01618     STATUS_SUCCESS if all goes well
    01619
    01620     The copy fails if the destination already exists or the source is read-only
    01621
    01622 --*/
    01623 {
    01624     NTSTATUS        Status;
    01625     HANDLE          SourceFile = NULL;
    01626     HANDLE          DestinationFile = NULL;
    01627     IO_STATUS_BLOCK SourceIoStatus;
    01628     IO_STATUS_BLOCK DestinationIoStatus;
    01629     ULONG           StreamInfoSize = 4096;
    01630     BYTE           *Buffer = NULL;
    01631     ULONG           BufferSize = 8192;
    01632
    01633     FILE_BASIC_INFORMATION      BasicInfo;
    01634     FILE_STANDARD_INFORMATION   StandardInfo;
    01635     FILE_STREAM_INFORMATION    *StreamInfo = NULL;
    01636     FILE_STREAM_INFORMATION    *Stream;
    01637
    01638     //
    01639     // Check the attributes on the source.  If it's set to
    01640     // read-only don't try to copy it
    01641     //
    01642
    01643     Status = NtUnRestrictedQueryAttributesFile(SourceAttributes, &BasicInfo);
    01644
    01645     if (!NT_SUCCESS(Status))
    01646         return Status;
    01647     else if (BasicInfo.FileAttributes & FILE_ATTRIBUTE_READONLY)
    01648         return STATUS_ACCESS_DENIED;
    01649
    01650
    01651     //
    01652     // Try to open the source file
    01653     //
    01654
    01655     Status = NtUnRestrictedOpenFile(
    01656                     &SourceFile,
    01657                     GENERIC_READ | SYNCHRONIZE,
    01658                     SourceAttributes,
    01659                     &SourceIoStatus,
    01660                     FILE_SHARE_READ,
    01661                     FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT);
    01662
    01663     if (!NT_SUCCESS(Status))
    01664         return Status;
    01665
    01666     //
    01667     // Get the size of the source.  If this fails don't worry about it.
    01668     //
    01669
    01670     Status = NtQueryInformationFile(
    01671                     SourceFile,
    01672                     &SourceIoStatus,
    01673                     &StandardInfo,
    01674                     sizeof(StandardInfo),
    01675                     FileStandardInformation);
    01676
    01677     if (!NT_SUCCESS(Status))
    01678         StandardInfo.AllocationSize.QuadPart = 0;
    01679
    01680     //
    01681     // Get the file stream information.  There's no way to tell how big a
    01682     // buffer we'll need to just keep doubling it.
    01683     //
    01684
    01685     do
    01686     {
    01687         StreamInfo = RtlAllocateHeap(RtlProcessHeap(), 0, StreamInfoSize);
    01688
    01689         if (NULL == StreamInfo)
    01690         {
    01691             Status = STATUS_NO_MEMORY;
    01692             goto ErrorOut;
    01693         }
    01694
    01695         Status = NtQueryInformationFile(
    01696                         SourceFile,
    01697                         &SourceIoStatus,
    01698                         StreamInfo,
    01699                         StreamInfoSize,
    01700                         FileStreamInformation);
    01701
    01702         StreamInfoSize *= 2;
    01703     }
    01704     while (STATUS_BUFFER_OVERFLOW == Status
    01705                || STATUS_BUFFER_TOO_SMALL == Status);
    01706
    01707     //
    01708     // Allocate a buffer to do the copying
    01709     //
    01710
    01711     do
    01712     {
    01713         Buffer = RtlAllocateHeap(RtlProcessHeap(), 0, BufferSize);
    01714
    01715         if (NULL == Buffer)
    01716             BufferSize /= 2;
    01717     }
    01718     while (NULL == Buffer && BufferSize > 15);
    01719
    01720     if (NULL == Buffer)
    01721         goto ErrorOut;
    01722
    01723     //
    01724     // Try to create the destination file
    01725     //
    01726
    01727     Status = NtUnRestrictedCreateFile(
    01728                     &DestinationFile,
    01729                     GENERIC_WRITE | SYNCHRONIZE,
    01730                     DestinationAttributes,
    01731                     &DestinationIoStatus,
    01732                     &StandardInfo.AllocationSize,
    01733                     BasicInfo.FileAttributes,
    01734                     0,
    01735                     FILE_CREATE,
    01736                     FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT,
    01737                     NULL,
    01738                     0);
    01739
    01740     //
    01741     // If creating the file failed because the path doesn't exist,
    01742     // create the path and try again
    01743     //
    01744
    01745     if (STATUS_OBJECT_PATH_NOT_FOUND == Status)
    01746     {
    01747         Status = CreateDirectories(DestinationAttributes);
    01748
    01749         if (NT_SUCCESS(Status))
    01750         {
    01751             Status = NtUnRestrictedCreateFile(
    01752                             &DestinationFile,
    01753                             GENERIC_WRITE | SYNCHRONIZE,
    01754                             DestinationAttributes,
    01755                             &DestinationIoStatus,
    01756                             &StandardInfo.AllocationSize,
    01757                             BasicInfo.FileAttributes,
    01758                             0,
    01759                             FILE_CREATE,
    01760                             FILE_SEQUENTIAL_ONLY |FILE_SYNCHRONOUS_IO_NONALERT,
    01761                             NULL,
    01762                             0);
    01763         }
    01764     }
    01765
    01766     if (!NT_SUCCESS(Status))
    01767         goto ErrorOut;
    01768
    01769     //
    01770     // Set the file times.  It's ok to fail
    01771     //
    01772
    01773     NtSetInformationFile(
    01774             DestinationFile,
    01775             &DestinationIoStatus,
    01776             &BasicInfo,
    01777             sizeof(BasicInfo),
    01778             FileBasicInformation);
    01779
    01780     //
    01781     // Copy each stream in the file
    01782     //
    01783
    01784     Stream = StreamInfo;
    01785
    01786     do
    01787     {
    01788         Status = CopyStream(
    01789                         SourceFile,
    01790                         DestinationFile,
    01791                         Stream,
    01792                         Buffer,
    01793                         BufferSize);
    01794
    01795         if (0 == Stream->NextEntryOffset)
    01796             break;
    01797
    01798         Stream = (FILE_STREAM_INFORMATION *)
    01799                         (((BYTE *) Stream) + Stream->NextEntryOffset);
    01800     }
    01801     while (NT_SUCCESS(Status));
    01802
    01803 ErrorOut:
    01804
    01805     if (NULL != Buffer)
    01806         RtlFreeHeap(RtlProcessHeap(), 0, Buffer);
    01807     if (NULL != StreamInfo)
    01808         RtlFreeHeap(RtlProcessHeap(), 0, StreamInfo);
    01809     if (NULL != SourceFile)
    01810         NtClose(SourceFile);
    01811
    01812     if (NULL != DestinationFile)
    01813     {
    01814         NtClose(DestinationFile);
    01815
    01816         if (!NT_SUCCESS(Status))
    01817         {
    01818             NTSTATUS DeleteStatus;
    01819             DeleteStatus = NtUnRestrictedDeleteFile(DestinationAttributes);
    01820             ASSERT(NT_SUCCESS(DeleteStatus));
    01821         }
    01822     }
    01823
    01824     return Status;
    01825 }

NTSTATUS CopyStream | ( | HANDLE | SourceFile,
|  | HANDLE | DestinationFile,
|  | FILE_STREAM_INFORMATION * | StreamInfo,
|  | BYTE * | Buffer,
|  | ULONG | BufferSize
| ) |

Definition at line 1451 of file restrfil.c.

References Buffer, BufferSize, L, NT_SUCCESS, NtClose(), NtReadFile(), NTSTATUS(), NtUnRestrictedCreateFile(), NtUnRestrictedOpenFile(), NtWriteFile(), NULL, Status, and USHORT.

Referenced by CopyRestrictedFile().

    01459                    :
    01460
    01461     Copy a stream from one file to another
    01462
    01463 Arguments:
    01464
    01465     SourceFile      - The source file
    01466     DestinationFile - The destination file
    01467     StreamInfo      - Information about the stream to copy
    01468     Buffer          - The buffer to use for copying
    01469     BufferSize      - The size of Buffer
    01470
    01471 Return Value:
    01472
    01473     STATUS_SUCCESS if all goes well
    01474
    01475 --*/
    01476 {
    01477     NTSTATUS            Status;
    01478     UNICODE_STRING      StreamName;
    01479     OBJECT_ATTRIBUTES   SourceAttributes;
    01480     OBJECT_ATTRIBUTES   DestinationAttributes;
    01481     HANDLE              SourceStream;
    01482     HANDLE              DestinationStream;
    01483     IO_STATUS_BLOCK     SourceIoStatus;
    01484     IO_STATUS_BLOCK     DestinationIoStatus;
    01485
    01486     StreamName.MaximumLength = (USHORT) StreamInfo->StreamNameLength;
    01487     StreamName.Length        = (USHORT) StreamInfo->StreamNameLength;
    01488     StreamName.Buffer        = StreamInfo->StreamName;
    01489
    01490     //
    01491     // Data stream names are of the form ":<name>:$DATA" so if the second
    01492     // char in the name is a colon then this is the default stream and we
    01493     // don't need to open/create it
    01494     //
    01495
    01496     if (L':' == StreamInfo->StreamName[1])
    01497     {
    01498         SourceStream = SourceFile;
    01499         DestinationStream = DestinationFile;
    01500     }
    01501     else
    01502     {
    01503         InitializeObjectAttributes(
    01504                 &SourceAttributes,
    01505                 &StreamName,
    01506                 OBJ_CASE_INSENSITIVE,
    01507                 SourceFile,
    01508                 NULL);
    01509         InitializeObjectAttributes(
    01510                 &DestinationAttributes,
    01511                 &StreamName,
    01512                 OBJ_CASE_INSENSITIVE,
    01513                 DestinationFile,
    01514                 NULL);
    01515
    01516         Status = NtUnRestrictedOpenFile(
    01517                         &SourceStream,
    01518                         GENERIC_READ | SYNCHRONIZE,
    01519                         &SourceAttributes,
    01520                         &SourceIoStatus,
    01521                         FILE_SHARE_READ,
    01522                         FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT);
    01523
    01524         if (!NT_SUCCESS(Status))
    01525             return Status;
    01526
    01527         Status = NtUnRestrictedCreateFile(
    01528                         &DestinationStream,
    01529                         GENERIC_WRITE | SYNCHRONIZE,
    01530                         &DestinationAttributes,
    01531                         &DestinationIoStatus,
    01532                         &StreamInfo->StreamAllocationSize,
    01533                         FILE_ATTRIBUTE_NORMAL,
    01534                         0,
    01535                         FILE_CREATE,
    01536                         FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT,
    01537                         NULL,
    01538                         0);
    01539
    01540         if (!NT_SUCCESS(Status))
    01541         {
    01542             NtClose(SourceStream);
    01543             return Status;
    01544         }
    01545     }
    01546
    01547     //
    01548     // Copy the stream
    01549     //
    01550
    01551     do
    01552     {
    01553         Status = NtReadFile(
    01554                         SourceStream,
    01555                         NULL,
    01556                         NULL,
    01557                         NULL,
    01558                         &SourceIoStatus,
    01559                         Buffer,
    01560                         BufferSize,
    01561                         0,
    01562                         NULL);
    01563
    01564         if (STATUS_END_OF_FILE == Status)
    01565         {
    01566             Status = STATUS_SUCCESS;
    01567             break;
    01568         }
    01569         else if (NT_SUCCESS(Status))
    01570         {
    01571             Status = NtWriteFile(
    01572                             DestinationStream,
    01573                             NULL,
    01574                             NULL,
    01575                             NULL,
    01576                             &DestinationIoStatus,
    01577                             Buffer,
    01578                             SourceIoStatus.Information,
    01579                             0,
    01580                             NULL);
    01581         }
    01582     }
    01583     while (NT_SUCCESS(Status) && SourceIoStatus.Information == BufferSize);
    01584
    01585     if (SourceStream != SourceFile)
    01586     {
    01587         NtClose(SourceStream);
    01588         NtClose(DestinationStream);
    01589     }
    01590
    01591     return Status;
    01592 }

NTSTATUS CreateDirectories | ( | OBJECT_ATTRIBUTES * | Attributes | ) |

Definition at line 1311 of file restrfil.c.

References ASSERT, L, NT_SUCCESS, NtClose(), NTSTATUS(), NtUnRestrictedCreateFile(), NULL, SiteDirectory, and Status.

Referenced by CopyRestrictedFile(), and NtCreateFile().

    01314                    :
    01315
    01316     Given the path pointed to by Attributes, make sure all the directories
    01317     above the last element in the path exist.
    01318
    01319 Parameters:
    01320
    01321     Attributes - The path
    01322
    01323 Return Value:
    01324
    01325     STATUS_SUCCESS if all goes well
    01326
    01327 --*/
    01328 {
    01329     NTSTATUS            Status;
    01330     UNICODE_STRING      SubDirectory;
    01331     OBJECT_ATTRIBUTES   DirectoryAttributes;
    01332     HANDLE              NewDirectory = NULL;
    01333     WCHAR              *NextDirectory;
    01334     WCHAR              *EndOfString;
    01335     IO_STATUS_BLOCK     IoStatus;
    01336
    01337     ASSERT(NULL == Attributes->RootDirectory);
    01338
    01339     InitializeObjectAttributes(
    01340             &DirectoryAttributes,
    01341             &SubDirectory,
    01342             OBJ_CASE_INSENSITIVE,
    01343             NULL,
    01344             NULL);
    01345
    01346     //
    01347     // Keep track of the end of the path and trim off any trailing '\'s
    01348     //
    01349
    01350     ASSERT(Attributes->ObjectName->Length >= 2);
    01351
    01352     EndOfString         = Attributes->ObjectName->Buffer
    01353                             + Attributes->ObjectName->Length / sizeof(WCHAR);
    01354
    01355     if (L'\\' == EndOfString[-1])
    01356         --EndOfString;
    01357
    01358     //
    01359     // Keep of a private version of the path so we can muck with it
    01360     //
    01361
    01362     SubDirectory.Buffer = Attributes->ObjectName->Buffer;
    01363     NextDirectory       = SubDirectory.Buffer;
    01364     NextDirectory      += SiteDirectory.Length / sizeof(WCHAR);
    01365
    01366     //
    01367     // For each element in the path, try to create a directory using the full
    01368     // path up to that element.
    01369     //
    01370     // Notes: CreateFile for "\??" returns STATUS_OBJECT_TYPE_MISMATCH
    01371     //        CreateFile for "\??\D:" returns STATUS_INVALID_PARAMETER
    01372     //
    01373
    01374     do
    01375     {
    01376         // Find the end of the next element
    01377
    01378         do
    01379         {
    01380             ++NextDirectory;
    01381         }
    01382         while (NextDirectory < EndOfString && L'\\' != *NextDirectory);
    01383
    01384         if ( !(NextDirectory < EndOfString) )
    01385             break;
    01386
    01387         // Adjust SubDirectory to include it
    01388
    01389         SubDirectory.Length        = (NextDirectory - SubDirectory.Buffer);
    01390         SubDirectory.Length       *= sizeof(WCHAR);
    01391         SubDirectory.MaximumLength = SubDirectory.Length;
    01392
    01393         // Create it
    01394
    01395         Status = NtUnRestrictedCreateFile(
    01396                         &NewDirectory,
    01397                         GENERIC_READ | SYNCHRONIZE,
    01398                         &DirectoryAttributes,
    01399                         &IoStatus,
    01400                         NULL,
    01401                         FILE_ATTRIBUTE_NORMAL,
    01402                         FILE_SHARE_READ | FILE_SHARE_WRITE,
    01403                         FILE_OPEN_IF,
    01404                         FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
    01405                         NULL,
    01406                         0);
    01407
    01408         if (NT_SUCCESS(Status))
    01409             NtClose(NewDirectory);
    01410
    01411         NewDirectory = NULL;
    01412     }
    01413     while ((NT_SUCCESS(Status)
    01414                     || STATUS_OBJECT_TYPE_MISMATCH == Status
    01415                     || STATUS_INVALID_PARAMETER    == Status)
    01416            && NextDirectory < EndOfString);
    01417
    01418     return Status;
    01419 }

BOOL FileExists | ( | OBJECT_ATTRIBUTES * | Attributes | ) |

Definition at line 1423 of file restrfil.c.

References BOOL, NtQueryAttributesFile(), NTSTATUS(), and Status.

Referenced by NtCreateFile().

    01427                    :
    01428
    01429     Determine if the given file/directory exists
    01430
    01431 Arguments:
    01432
    01433     Attributes      - The file/directory to check
    01434
    01435 Return Value:
    01436
    01437     TRUE if it exists
    01438
    01439 --*/
    01440 {
    01441     NTSTATUS                Status;
    01442     FILE_BASIC_INFORMATION  FileInfo;
    01443
    01444     Status = NtQueryAttributesFile(Attributes, &FileInfo);
    01445
    01446     return (STATUS_SUCCESS == Status);
    01447 }

HRESULT GetMangledSiteSid | ( | PSID | pSid,
|  | ULONG | cchMangledSite,
|  | LPWSTR * | ppwszMangledSite
| ) |

Definition at line 1915 of file restrfil.c.

References ASSERT, Base32Encode(), DWORD, RtlSubAuthorityCountSid(), and RtlSubAuthoritySid().

    01916 {
    01917     if (cchMangledSite < MAX_MANGLED_SITE)
    01918     {
    01919 /*        *ppwszMangledSite = (WCHAR *) LocalAlloc(
    01920                                             0,
    01921                                             MAX_MANGLED_SITE * sizeof(WCHAR));*/
    01922 //        if (NULL == *ppwszMangledSite)
    01923             return E_OUTOFMEMORY;
    01924     }
    01925
    01926     // The value of MAX_MANGLED_SITE assumes 4 dwords
    01927     ASSERT(4 == *RtlSubAuthorityCountSid(pSid));
    01928
    01929     Base32Encode(
    01930             RtlSubAuthoritySid(pSid, 0),
    01931             *RtlSubAuthorityCountSid(pSid) * sizeof(DWORD),
    01932             *ppwszMangledSite);
    01933
    01934     // The output string should always be MAX_MANGLED_SITE - 1 chars long
    01935     ASSERT(MAX_MANGLED_SITE - 1 == wcslen(*ppwszMangledSite));
    01936
    01937     return S_OK;
    01938 }

PSID GetSiteSidFromToken | ( | IN HANDLE | TokenHandle | ) |

Definition at line 1844 of file restrfil.c.

References NT_SUCCESS, NtQueryInformationToken(), NTSTATUS(), NULL, RtlAllocateHeap, RtlCopySid(), RtlFreeHeap, RtlLengthSid(), Status, and UINT.

    01847 {
    01848     PTOKEN_GROUPS RestrictedSids = NULL;
    01849     ULONG ReturnLength;
    01850     NTSTATUS Status;
    01851     PSID psSiteSid = NULL;
    01852
    01853
    01854     Status = NtQueryInformationToken(
    01855         TokenHandle,
    01856         TokenRestrictedSids,
    01857         NULL,
    01858         0,
    01859         &ReturnLength
    01860         );
    01861     if (Status != STATUS_BUFFER_TOO_SMALL)
    01862     {
    01863         //BaseSetLastNTError(Status);
    01864         return NULL;
    01865     }
    01866
    01867     RestrictedSids = (PTOKEN_GROUPS) RtlAllocateHeap(RtlProcessHeap(), 0, ReturnLength);
    01868     if (RestrictedSids == NULL)
    01869     {
    01870 //        SetLastError(ERROR_OUTOFMEMORY);
    01871         return NULL;
    01872     }
    01873
    01874     Status = NtQueryInformationToken(
    01875         TokenHandle,
    01876         TokenRestrictedSids,
    01877         RestrictedSids,
    01878         ReturnLength,
    01879         &ReturnLength
    01880         );
    01881     if (NT_SUCCESS(Status))
    01882     {
    01883         UINT i;
    01884         SID_IDENTIFIER_AUTHORITY InternetSiteAuthority = SECURITY_INTERNETSITE_AUTHORITY;
    01885
    01886         for (i = 0; i < RestrictedSids->GroupCount; i++) {
    01887
    01888             if (RtlCompareMemory((PVOID) &((SID *) RestrictedSids->Groups[i].Sid)->IdentifierAuthority,
    01889                 (PVOID) &InternetSiteAuthority,
    01890                 sizeof(SID_IDENTIFIER_AUTHORITY)) == sizeof(SID_IDENTIFIER_AUTHORITY))
    01891             {
    01892                 psSiteSid = RtlAllocateHeap(RtlProcessHeap(), 0, RtlLengthSid((RestrictedSids->Groups[i]).Sid));
    01893                 if (psSiteSid == NULL) {
    01894 //                    SetLastError(ERROR_OUTOFMEMORY);
    01895                 }
    01896                 else {
    01897                     RtlCopySid(RtlLengthSid((RestrictedSids->Groups[i]).Sid), psSiteSid, (RestrictedSids->Groups[i]).Sid);
    01898                 }
    01899
    01900                 break;
    01901             }
    01902
    01903         }
    01904     }
    01905     else
    01906     {
    01907         //BaseSetLastNTError(Status);
    01908     }
    01909
    01910     RtlFreeHeap(RtlProcessHeap(), 0, RestrictedSids);
    01911     return psSiteSid;
    01912 }

NTSTATUS InitializeRestrictedStuff | ( |  | ) |

Definition at line 879 of file restrfil.c.

References BOOL, Buffer, BufferSize, FALSE, GetMangledSiteSid, GetSiteSidFromToken, Initialized, L, NT_SUCCESS, NtClose(), NtOpenKey(), NtOpenProcessToken(), NtQueryObject(), NtQueryValueKey(), NTSTATUS(), NtUnRestrictedOpenFile(), NULL, RtlAllocateHeap, RtlAppendUnicodeToString(), RtlCreateUnicodeString(), RtlExpandEnvironmentStrings_U(), RtlFormatCurrentUserKeyPath(), RtlFreeHeap, RtlFreeSid(), RtlFreeUnicodeString(), RtlInitUnicodeString(), SiteDirectory, Status, SystemPath1, SystemPath2, SystemPath3, and USHORT.

Referenced by CheckRestricted().

    00882                    :
    00883
    00884     Determine if this process needs to have file mapping turned on and if so
    00885     figure out the paths to the system drive and shadow area
    00886
    00887 Arguments:
    00888
    00889     None
    00890
    00891 Return Value:
    00892
    00893     STATUS_SUCCESS if file mapping support was initialized.
    00894
    00895 --*/
    00896 {
    00897     OBJECT_ATTRIBUTES   Attributes;
    00898     UNICODE_STRING      Path;
    00899     UNICODE_STRING      ProfileDirectory;
    00900     HKEY                ProfileKey;
    00901     HKEY                UserProfileKey;
    00902     WCHAR               Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION)+128/sizeof(WCHAR)];
    00903     ULONG               BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION)+128;
    00904     IO_STATUS_BLOCK     IoStatus;
    00905     NTSTATUS            Status;
    00906     HANDLE              SystemRoot;
    00907     UNICODE_STRING     *TempString;
    00908
    00909     HANDLE              hToken;
    00910     PSID                SiteSid;
    00911     WCHAR               MangledSiteBuffer[MAX_MANGLED_SITE];
    00912     LPWSTR              MangledSite = MangledSiteBuffer;
    00913
    00914     static BOOL         Initialized = FALSE;
    00915
    00916     KEY_VALUE_PARTIAL_INFORMATION  *KeyInfo;
    00917
    00918     if (Initialized)
    00919         return STATUS_SUCCESS;
    00920
    00921     //
    00922     // Figure out the path to \Device<systemvolume>.  We need to open a
    00923     // handle to SystemRoot and then query the name of that handle.
    00924     //
    00925
    00926     Path.MaximumLength = sizeof(Buffer);
    00927     Path.Length        = 0;
    00928     Path.Buffer        = Buffer;
    00929     RtlAppendUnicodeToString(&Path, L"\\??\\");
    00930     RtlAppendUnicodeToString(&Path, USER_SHARED_DATA->NtSystemRoot);
    00931
    00932     InitializeObjectAttributes(
    00933             &Attributes,
    00934             &Path,
    00935             OBJ_CASE_INSENSITIVE,
    00936             NULL,
    00937             NULL);
    00938
    00939     Status = NtUnRestrictedOpenFile(
    00940                         &SystemRoot,
    00941                         GENERIC_READ | SYNCHRONIZE,
    00942                         &Attributes,
    00943                         &IoStatus,
    00944                         FILE_SHARE_READ | FILE_SHARE_WRITE,
    00945                         FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    00946
    00947     if (!NT_SUCCESS(Status))
    00948         return Status;
    00949
    00950     Status = NtQueryObject(
    00951                     SystemRoot,
    00952                     ObjectNameInformation,
    00953                     Buffer,
    00954                     sizeof(Buffer),
    00955                     NULL);
    00956
    00957     NtClose(SystemRoot);
    00958
    00959     if (!NT_SUCCESS(Status))
    00960         return Status;
    00961
    00962     // The path is the name of the SystemRoot handle minus the length of
    00963     // NtSystemRoot minus the drive letter
    00964
    00965     TempString = & ((OBJECT_NAME_INFORMATION *) Buffer)->Name;
    00966     TempString->Length -= sizeof(WCHAR) *
    00967                                     (wcslen(USER_SHARED_DATA->NtSystemRoot)
    00968                                                 - sizeof("d"));
    00969
    00970     TempString->Buffer[TempString->Length / sizeof(WCHAR)] = L'\0';
    00971
    00972     Status = RtlCreateUnicodeString(
    00973                         &SystemPath1,
    00974                         TempString->Buffer);
    00975
    00976     if (!NT_SUCCESS(Status))
    00977         return Status;
    00978
    00979 //DbgPrint("SystemPath1 = %wZ\n", &SystemPath1);
    00980
    00981     // Figure out the path to \??<systemdrive>
    00982
    00983     Path.Length        = 0;
    00984     Path.Buffer        = Buffer;
    00985     RtlAppendUnicodeToString(&Path, L"\\??\\");
    00986     RtlAppendUnicodeToString(&Path, USER_SHARED_DATA->NtSystemRoot);
    00987     Path.Buffer[sizeof("\\??\\d")] = L'\0';
    00988
    00989     Status = RtlCreateUnicodeString(&SystemPath2, Path.Buffer);
    00990
    00991     if (!NT_SUCCESS(Status))
    00992         return Status;
    00993
    00994 //DbgPrint("SystemPath2 = %wZ\n", &SystemPath2);
    00995
    00996     // Figure out the path to \DosDevices<systemdrive>
    00997
    00998     Path.Length        = 0;
    00999     Path.Buffer        = Buffer;
    01000     RtlAppendUnicodeToString(&Path, L"\\DosDevices\\");
    01001     RtlAppendUnicodeToString(&Path, USER_SHARED_DATA->NtSystemRoot);
    01002     Path.Buffer[sizeof("\\DosDevices\\d")] = L'\0';
    01003
    01004     Status = RtlCreateUnicodeString(&SystemPath3, Path.Buffer);
    01005
    01006     if (!NT_SUCCESS(Status))
    01007         return Status;
    01008
    01009 //DbgPrint("SystemPath3 = %wZ\n", &SystemPath3);
    01010
    01011     //
    01012     // Figure out where the site directory is
    01013     //
    01014     // This code is temporary.  Eventually the shadow directory will be stored
    01015     // in the job object
    01016     //
    01017
    01018     // First open the list of profile locations
    01019
    01020     RtlInitUnicodeString(&Path, L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList");
    01021
    01022     InitializeObjectAttributes(
    01023             &Attributes,
    01024             &Path,
    01025             OBJ_CASE_INSENSITIVE,
    01026             NULL,
    01027             NULL);
    01028
    01029     Status = NtOpenKey(&ProfileKey, KEY_READ, &Attributes);
    01030
    01031     if (!NT_SUCCESS(Status))
    01032         return Status;
    01033
    01034     // Next get a stringized version of the user's SID
    01035
    01036     Status = RtlFormatCurrentUserKeyPath(&Path);
    01037
    01038     if (!NT_SUCCESS(Status))
    01039     {
    01040         NtClose(ProfileKey);
    01041         return Status;
    01042     }
    01043
    01044     Path.Buffer += sizeof("\\Registry\\User");
    01045     Path.Length -= sizeof(L"\\Registry\\User");
    01046
    01047     // And open the profile for the current user
    01048
    01049     Attributes.RootDirectory = ProfileKey;
    01050
    01051     Status = NtOpenKey(&UserProfileKey, KEY_READ, &Attributes);
    01052
    01053     NtClose(ProfileKey);
    01054     Path.Buffer -= sizeof("\\Registry\\User");
    01055     Path.Length += sizeof(L"\\Registry\\User");
    01056     RtlFreeUnicodeString(&Path);
    01057
    01058     if (!NT_SUCCESS(Status))
    01059         return Status;
    01060
    01061     // Allocate a buffer and get the info
    01062
    01063     RtlInitUnicodeString(&Path, L"ProfileImagePath");
    01064
    01065     do
    01066     {
    01067         ULONG ResultLength;
    01068
    01069         KeyInfo = RtlAllocateHeap(RtlProcessHeap(), 0, BufferSize);
    01070
    01071         if (NULL == KeyInfo)
    01072         {
    01073             NtClose(UserProfileKey);
    01074             Status = STATUS_NO_MEMORY;
    01075             break;
    01076         }
    01077
    01078         Status = NtQueryValueKey(
    01079                         UserProfileKey,
    01080                         &Path,
    01081                         KeyValuePartialInformation,
    01082                         KeyInfo,
    01083                         BufferSize,
    01084                         &ResultLength);
    01085
    01086         if (!NT_SUCCESS(Status))
    01087         {
    01088             BufferSize *= 2;
    01089             RtlFreeHeap(RtlProcessHeap(), 0, KeyInfo);
    01090         }
    01091     }
    01092     while (   STATUS_BUFFER_OVERFLOW == Status
    01093            || STATUS_BUFFER_TOO_SMALL == Status);
    01094
    01095     NtClose(UserProfileKey);
    01096
    01097     if (!NT_SUCCESS(Status))
    01098         return Status;
    01099
    01100     // Create the path to the site directory
    01101
    01102     Path.Length         = 0;
    01103     Path.MaximumLength  = sizeof(Buffer);
    01104     Path.Buffer         = Buffer;
    01105
    01106     ProfileDirectory.Length        = (USHORT) KeyInfo->DataLength;
    01107     ProfileDirectory.MaximumLength = (USHORT) KeyInfo->DataLength;
    01108     ProfileDirectory.Buffer        = (WCHAR *) KeyInfo->Data;
    01109
    01110     Status = RtlExpandEnvironmentStrings_U(NULL, &ProfileDirectory, &Path, NULL);
    01111
    01112     if (!NT_SUCCESS(Status))
    01113         return Status;
    01114
    01115     // RtlExpandEnvironmentStrings_U includes the null terminator in the length
    01116
    01117     Path.Length        -= sizeof(L'\0');
    01118
    01119     // Remove the drive letter from the path
    01120
    01121     Path.Length        -= 2 * sizeof(WCHAR);
    01122     MoveMemory(Path.Buffer, Path.Buffer + 2, Path.Length);
    01123
    01124     //
    01125     // Figure out the site directory name
    01126     //
    01127
    01128     Status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_READ, &hToken);
    01129
    01130     if (!NT_SUCCESS(Status))
    01131         return Status;
    01132
    01133     SiteSid = GetSiteSidFromToken(hToken);
    01134
    01135     NtClose(hToken);
    01136
    01137     if (NULL == SiteSid)
    01138         return STATUS_UNSUCCESSFUL;
    01139
    01140     Status = GetMangledSiteSid(SiteSid, MAX_MANGLED_SITE, &MangledSite);
    01141
    01142     RtlFreeSid(SiteSid);
    01143
    01144     if (!NT_SUCCESS(Status))
    01145         return Status;
    01146
    01147     RtlAppendUnicodeToString(&Path, L"\\");
    01148     RtlAppendUnicodeToString(&Path, MangledSite);
    01149
    01150     Path.Buffer[Path.Length / sizeof(WCHAR)] = L'\0';
    01151
    01152     Status = RtlCreateUnicodeString(&SiteDirectory, Path.Buffer);
    01153
    01154 //DbgPrint("Site Directory = %wZ\n", &SiteDirectory);
    01155
    01156     Initialized = NT_SUCCESS(Status);
    01157
    01158     return Status;
    01159 }

BOOL IsInterestingPath | ( | IN POBJECT_ATTRIBUTES | NormalFile,
|  | IN OUT POBJECT_ATTRIBUTES | RestrictedFile
| ) |

Definition at line 1163 of file restrfil.c.

References BOOL, Buffer, BYTE, FALSE, L, NT_SUCCESS, NtQueryObject(), NTSTATUS(), NULL, RtlAllocateHeap, RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), RtlCopyUnicodeString(), RtlPrefixUnicodeString(), SiteDirectory, Status, SystemPath1, SystemPath2, SystemPath3, and TRUE.

Referenced by NtCreateFile(), NtDeleteFile(), NtOpenFile(), NtQueryAttributesFile(), and NtSetInformationFile().

    01168                    :
    01169
    01170     Determine if this path pointed to by NormalFile can be mapped and if so
    01171     point RestrictedFile at the mapped version
    01172
    01173 Arguments:
    01174
    01175     NormalFile - The file to be tested
    01176     RestrictedFile - The resultant restricted file
    01177
    01178 Return Value:
    01179
    01180     STATUS_SUCCESS if RestrictedFile was setup
    01181
    01182 --*/
    01183 {
    01184     BYTE                    Buffer[1024];
    01185     OBJECT_NAME_INFORMATION *NameInfo = (OBJECT_NAME_INFORMATION *) Buffer;
    01186     NTSTATUS                Status;
    01187     BOOLEAN                 CaseInSensitive;
    01188     UNICODE_STRING         *SystemPath = NULL;
    01189     UNICODE_STRING         *RestrictedName;
    01190
    01191     //
    01192     // Expand out the root directory of a relative path, if applicable
    01193     //
    01194
    01195     if (NULL != NormalFile->RootDirectory)
    01196     {
    01197         WCHAR  LastChar;
    01198
    01199         // Get the name corresponding to the root handle
    01200
    01201         Status = NtQueryObject(
    01202                         NormalFile->RootDirectory,
    01203                         ObjectNameInformation,
    01204                         NameInfo,
    01205                         sizeof(Buffer),
    01206                         NULL);
    01207
    01208         if (!NT_SUCCESS(Status))
    01209             return FALSE;
    01210
    01211         // Make sure there's a backslash on the end
    01212
    01213         LastChar = NameInfo->Name.Buffer[
    01214                                 (NameInfo->Name.Length-1)*sizeof(WCHAR)];
    01215
    01216         if (L'\\' != LastChar)
    01217         {
    01218             Status = RtlAppendUnicodeToString(&NameInfo->Name, L"\\");
    01219
    01220             if (!NT_SUCCESS(Status))
    01221                 return FALSE;
    01222         }
    01223     }
    01224     else
    01225     {
    01226         NameInfo->Name.Length = 0;
    01227         NameInfo->Name.Buffer = (WCHAR *) (((BYTE *) NameInfo)
    01228                                                         + sizeof(*NameInfo));
    01229     }
    01230
    01231     //
    01232     // Concatenate the file/directory to it's root to get a full path
    01233     //
    01234
    01235     NameInfo->Name.MaximumLength = sizeof(Buffer)
    01236                                         - sizeof(*NameInfo)
    01237                                         - NameInfo->Name.Length;
    01238
    01239     Status = RtlAppendUnicodeStringToString(
    01240                             &NameInfo->Name,
    01241                             NormalFile->ObjectName);
    01242
    01243     if (!NT_SUCCESS(Status))
    01244         return FALSE;
    01245
    01246     //
    01247     // Check to see if the path should be mapped
    01248     //
    01249
    01250     CaseInSensitive = (BOOLEAN)
    01251                         ((OBJ_CASE_INSENSITIVE & NormalFile->Attributes) != 0);
    01252
    01253     if (RtlPrefixUnicodeString(&SystemPath1, &NameInfo->Name, CaseInSensitive))
    01254         SystemPath = &SystemPath1;
    01255     else
    01256     if (RtlPrefixUnicodeString(&SystemPath2, &NameInfo->Name, CaseInSensitive))
    01257         SystemPath = &SystemPath2;
    01258     else
    01259     if (RtlPrefixUnicodeString(&SystemPath3, &NameInfo->Name, CaseInSensitive))
    01260         SystemPath = &SystemPath3;
    01261
    01262     if (NULL == SystemPath)
    01263         return FALSE;
    01264
    01265     //
    01266     // This path is on the system drive, reject it if it's pointing at the
    01267     // mapped area already
    01268     //
    01269
    01270     NameInfo->Name.Length -= SystemPath->Length;
    01271     NameInfo->Name.Buffer += SystemPath->Length / sizeof(WCHAR);
    01272
    01273     if (RtlPrefixUnicodeString(&SiteDirectory,&NameInfo->Name,CaseInSensitive))
    01274         return FALSE;
    01275
    01276     NameInfo->Name.Length += SystemPath->Length;
    01277     NameInfo->Name.Buffer -= SystemPath->Length / sizeof(WCHAR);
    01278
    01279     //
    01280     // This path should be mapped
    01281     //
    01282
    01283     RestrictedName = RestrictedFile->ObjectName;
    01284     RestrictedName->MaximumLength = SystemPath1.Length
    01285                                     + SiteDirectory.Length
    01286                                     + NameInfo->Name.Length;
    01287     RestrictedName->Buffer = RtlAllocateHeap(
    01288                                     RtlProcessHeap(),
    01289                                     0,
    01290                                     RestrictedName->MaximumLength);
    01291
    01292     if (NULL == RestrictedName->Buffer)
    01293         return FALSE;
    01294
    01295     NameInfo->Name.Buffer[NameInfo->Name.Length] = L'\0';
    01296
    01297     RestrictedFile->RootDirectory = NULL;
    01298     RestrictedName->Length = 0;
    01299
    01300     RtlCopyUnicodeString(RestrictedName, &SystemPath1);
    01301     RtlAppendUnicodeStringToString(RestrictedName, &SiteDirectory);
    01302     RtlAppendUnicodeToString(
    01303                 RestrictedName,
    01304                 NameInfo->Name.Buffer + SystemPath->Length / sizeof(WCHAR));
    01305
    01306     return TRUE;
    01307 }

BOOL IsInterestingPath | ( | OBJECT_ATTRIBUTES * | NormalFile,
|  | OBJECT_ATTRIBUTES * | RestrictedFile
| ) |

__inline BOOL IsRestricted | ( |  | ) |

Definition at line 223 of file restrfil.c.

References CheckRestricted(), eRestricted, eUnknownRestricted, eUnRestricted, FALSE, and Restricted.

Referenced by NtCreateFile(), NtDeleteFile(), NtOpenFile(), NtQueryAttributesFile(), NtSetInformationFile(), xxxCallHook2(), and xxxProcessNotifyWinEvent().

    00226                    :
    00227
    00228     Determine if this is a restricted process and thus should have filesystem
    00229     redirection active.
    00230
    00231 Arguments:
    00232
    00233     None
    00234
    00235 Return Value:
    00236
    00237     TRUE if this is a restricted process, otherwise FALSE
    00238
    00239 --*/
    00240 {
    00241     if (eUnRestricted == Restricted)
    00242         return FALSE;
    00243
    00244     if (eUnknownRestricted == Restricted)
    00245         CheckRestricted();
    00246
    00247     return (eRestricted == Restricted);
    00248 }

BOOL IsTokenRestricted | ( | IN HANDLE | TokenHandle | ) |

Definition at line 2001 of file restrfil.c.

References BOOL, FALSE, NT_SUCCESS, NtQueryInformationToken(), NTSTATUS(), NULL, RtlAllocateHeap, RtlFreeHeap, Status, and TRUE.

    02004 {
    02005     PTOKEN_GROUPS RestrictedSids = NULL;
    02006     ULONG ReturnLength;
    02007     NTSTATUS Status;
    02008     BOOL Result = FALSE;
    02009
    02010
    02011     Status = NtQueryInformationToken(
    02012                 TokenHandle,
    02013                 TokenRestrictedSids,
    02014                 NULL,
    02015                 0,
    02016                 &ReturnLength
    02017                 );
    02018     if (Status != STATUS_BUFFER_TOO_SMALL)
    02019     {
    02020 //        BaseSetLastNTError(Status);
    02021         return(FALSE);
    02022     }
    02023
    02024     RestrictedSids = (PTOKEN_GROUPS) RtlAllocateHeap(RtlProcessHeap(), 0, ReturnLength);
    02025     if (RestrictedSids == NULL)
    02026     {
    02027 //        SetLastError(ERROR_OUTOFMEMORY);
    02028         return(FALSE);
    02029     }
    02030
    02031     Status = NtQueryInformationToken(
    02032                 TokenHandle,
    02033                 TokenRestrictedSids,
    02034                 RestrictedSids,
    02035                 ReturnLength,
    02036                 &ReturnLength
    02037                 );
    02038     if (NT_SUCCESS(Status))
    02039     {
    02040         if (RestrictedSids->GroupCount != 0)
    02041         {
    02042             Result = TRUE;
    02043         }
    02044     }
    02045     else
    02046     {
    02047 //        BaseSetLastNTError(Status);
    02048     }
    02049     RtlFreeHeap(RtlProcessHeap(), 0, RestrictedSids);
    02050     return(Result);
    02051 }

NTSTATUS NtCreateFile | ( | OUT PHANDLE | FileHandle,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN POBJECT_ATTRIBUTES | ObjectAttributes,
|  | OUT PIO_STATUS_BLOCK | IoStatusBlock,
|  | IN PLARGE_INTEGER AllocationSize | OPTIONAL,
|  | IN ULONG | FileAttributes,
|  | IN ULONG | ShareAccess,
|  | IN ULONG | CreateDisposition,
|  | IN ULONG | CreateOptions,
|  | IN PVOID EaBuffer | OPTIONAL,
|  | IN ULONG | EaLength
| ) |

Definition at line 253 of file restrfil.c.

References CALL_CREATE, CopyRestrictedFile(), CreateDirectories(), FileExists(), IsInterestingPath(), IsRestricted(), NT_SUCCESS, NTSTATUS(), ObjectAttributes, RtlFreeHeap, and Status.

    00268                    :
    00269
    00270     Entry point for the restricted version of NtCreateFile
    00271
    00272 Arguments:
    00273
    00274     FileHandle - A pointer to a variable to receive the handle to the open file.
    00275
    00276     DesiredAccess - Supplies the types of access that the caller would like to
    00277         the file.
    00278
    00279     ObjectAttributes - Supplies the attributes to be used for file object (name,
    00280         SECURITY_DESCRIPTOR, etc.)
    00281
    00282     IoStatusBlock - Specifies the address of the caller's I/O status block.
    00283
    00284     AllocationSize - Initial size that should be allocated to the file.  This
    00285         parameter only has an affect if the file is created.  Further, if
    00286         not specified, then it is taken to mean zero.
    00287
    00288     FileAttributes - Specifies the attributes that should be set on the file,
    00289         if it is created.
    00290
    00291     ShareAccess - Supplies the types of share access that the caller would like
    00292         to the file.
    00293
    00294     CreateDisposition - Supplies the method for handling the create/open.
    00295
    00296     CreateOptions - Caller options for how to perform the create/open.
    00297
    00298     EaBuffer - Optionally specifies a set of EAs to be applied to the file if
    00299         it is created.
    00300
    00301     EaLength - Supplies the length of the EaBuffer.
    00302
    00303 Return Value:
    00304
    00305     The function value is the final status of the create/open operation.
    00306
    00307 --*/
    00308 {
    00309 #define CALL_CREATE(object)                 \
    00310             NtUnRestrictedCreateFile(       \
    00311                     FileHandle,             \
    00312                     DesiredAccess,          \
    00313                     object,                 \
    00314                     IoStatusBlock,          \
    00315                     AllocationSize,         \
    00316                     FileAttributes,         \
    00317                     ShareAccess,            \
    00318                     CreateDisposition,      \
    00319                     CreateOptions,          \
    00320                     EaBuffer,               \
    00321                     EaLength)
    00322     /*\
    00323         ((st =                                       \
    00324        ) ? st                                        \
    00325     :  ((Restricted == eRestricted) ? DbgPrint("%s %wZ\n", (object==NormalFile)?"UnMapped":"  Mapped",object->ObjectName) : 0), st)
    00326 */
    00327
    00328     NTSTATUS            Status;
    00329     OBJECT_ATTRIBUTES  *OriginalAttributes;
    00330     OBJECT_ATTRIBUTES  *NormalFile;
    00331     OBJECT_ATTRIBUTES   RestrictedFileAttributes;
    00332     OBJECT_ATTRIBUTES  *RestrictedFile = &RestrictedFileAttributes;
    00333     UNICODE_STRING      RestrictedObjectName;
    00334
    00335     FILE_BASIC_INFORMATION  BasicInfo;
    00336
    00337 //NTSTATUS st;
    00338
    00339     if (!IsRestricted())
    00340         return CALL_CREATE(ObjectAttributes);
    00341
    00342     //
    00343     // Check to see if this file is mappable.  If not don't try
    00344     //
    00345
    00346     NormalFile = ObjectAttributes;
    00347
    00348     CopyMemory(RestrictedFile, NormalFile, sizeof(OBJECT_ATTRIBUTES));
    00349     RestrictedFile->ObjectName = &RestrictedObjectName;
    00350
    00351     if (!IsInterestingPath(NormalFile, RestrictedFile))
    00352         return CALL_CREATE(NormalFile);
    00353
    00354     //
    00355     // The file/directory is mappable
    00356     //
    00357
    00358     //
    00359     // If this is a directory, try to access the normal one first, then the
    00360     // shadowed one
    00361     //
    00362     if (CreateOptions & FILE_DIRECTORY_FILE)
    00363     {
    00364         Status = CALL_CREATE(NormalFile);
    00365
    00366         if (!NT_SUCCESS(Status))
    00367         {
    00368             Status = CALL_CREATE(RestrictedFile);
    00369         }
    00370     }
    00371
    00372     //
    00373     // If this is a file which which already has a shadowed version, try the
    00374     // operation only on that version
    00375     //
    00376     else if (FileExists(RestrictedFile))
    00377     {
    00378         Status = CALL_CREATE(RestrictedFile);
    00379     }
    00380
    00381     //
    00382     // This is a file operation and no shadowed version of the file exists,
    00383     // try the operation in the unshadowed area
    00384     //
    00385     else
    00386     {
    00387         Status = CALL_CREATE(NormalFile);
    00388
    00389         if (STATUS_ACCESS_DENIED == Status)
    00390         {
    00391             Status = CreateDirectories(RestrictedFile);
    00392
    00393             if (NT_SUCCESS(Status))
    00394             {
    00395                 Status = CopyRestrictedFile(NormalFile, RestrictedFile);
    00396
    00397                 if (NT_SUCCESS(Status)
    00398                     || STATUS_OBJECT_NAME_NOT_FOUND == Status)
    00399                 {
    00400                     Status = CALL_CREATE(RestrictedFile);
    00401                 }
    00402             }
    00403         }
    00404     }
    00405
    00406
    00407 /*
    00408 if (!NT_SUCCESS(Status))
    00409   DbgPrint("  Failed %wZ\n", NormalFile->ObjectName);
    00410 */
    00411     RtlFreeHeap(RtlProcessHeap(), 0, RestrictedObjectName.Buffer);
    00412
    00413     return Status;
    00414
    00415 #undef CALL_CREATE
    00416 }
    NTSTATUS

NTSTATUS NtDeleteFile | ( | IN POBJECT_ATTRIBUTES | ObjectAttributes | ) |

Definition at line 602 of file restrfil.c.

References IsInterestingPath(), IsRestricted(), NT_SUCCESS, NTSTATUS(), NtUnRestrictedDeleteFile(), ObjectAttributes, RtlFreeHeap, and Status.

    00605                    :
    00606
    00607     Attempt to delete the shadowed version of the given file.  If that fails
    00608     attempt to delete the real version of the file
    00609
    00610 Arguments:
    00611
    00612     ObjectAttributes - Supplies the attributes to be used for file object (name,
    00613         SECURITY_DESCRIPTOR, etc.)
    00614
    00615 Return Value:
    00616
    00617     The status returned is the final completion status of the operation.
    00618
    00619 --*/
    00620 {
    00621     NTSTATUS            Status;
    00622     OBJECT_ATTRIBUTES  *NormalFile;
    00623     OBJECT_ATTRIBUTES   RestrictedFileAttributes;
    00624     OBJECT_ATTRIBUTES  *RestrictedFile = &RestrictedFileAttributes;
    00625     UNICODE_STRING      RestrictedObjectName;
    00626
    00627     if (!IsRestricted())
    00628         return NtUnRestrictedDeleteFile(ObjectAttributes);
    00629
    00630     //
    00631     // Check to see if this file is mappable.  Map it if it is
    00632     //
    00633
    00634     NormalFile = ObjectAttributes;
    00635
    00636     CopyMemory(RestrictedFile, NormalFile, sizeof(OBJECT_ATTRIBUTES));
    00637     RestrictedFile->ObjectName = &RestrictedObjectName;
    00638
    00639     if (IsInterestingPath(NormalFile, RestrictedFile))
    00640     {
    00641         Status = NtUnRestrictedDeleteFile(RestrictedFile);
    00642
    00643         RtlFreeHeap(RtlProcessHeap(), 0, RestrictedObjectName.Buffer);
    00644
    00645         if (NT_SUCCESS(Status) || STATUS_ACCESS_DENIED == Status)
    00646             return Status;
    00647     }
    00648
    00649     //
    00650     // The file is not mappable or deleting the mapped version failed.
    00651     //
    00652
    00653     return NtUnRestrictedDeleteFile(NormalFile);
    00654 }
    NTSTATUS ZwDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)

NTSTATUS NtOpenFile | ( | OUT PHANDLE | FileHandle,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN POBJECT_ATTRIBUTES | ObjectAttributes,
|  | OUT PIO_STATUS_BLOCK | IoStatusBlock,
|  | IN ULONG | ShareAccess,
|  | IN ULONG | OpenOptions
| ) |

Definition at line 449 of file restrfil.c.

References CALL_OPEN, CopyRestrictedFile(), IsInterestingPath(), IsRestricted(), NT_SUCCESS, NTSTATUS(), ObjectAttributes, RtlFreeHeap, and Status.

    00459                    :
    00460
    00461     Entry point for the restricted version of NtOpenFile
    00462
    00463 Arguments:
    00464
    00465     FileHandle - A pointer to a variable to receive the handle to the open file.
    00466
    00467     DesiredAccess - Supplies the types of access that the caller would like to
    00468         the file.
    00469
    00470     ObjectAttributes - Supplies the attributes to be used for file object (name,
    00471         SECURITY_DESCRIPTOR, etc.)
    00472
    00473     IoStatusBlock - Specifies the address of the caller's I/O status block.
    00474
    00475     ShareAccess - Supplies the types of share access that the caller would like
    00476         to the file.
    00477
    00478     OpenOptions - Caller options for how to perform the open.
    00479
    00480 Return Value:
    00481
    00482     The function value is the final completion status of the open/create
    00483     operation.
    00484
    00485 --*/
    00486 {
    00487 #define CALL_OPEN(object)                 \
    00488             NtUnRestrictedOpenFile(       \
    00489                     FileHandle,             \
    00490                     DesiredAccess,          \
    00491                     object,                 \
    00492                     IoStatusBlock,          \
    00493                     ShareAccess,            \
    00494                     OpenOptions)
    00495     /*\
    00496         ((st =                                       \
    00497        ) ? st                                        \
    00498     :  ((Restricted == eRestricted) ? DbgPrint("%s %wZ\n", (object==NormalFile)?"UnMapped":"  Mapped",object->ObjectName) : 0), st)
    00499 */
    00500
    00501     NTSTATUS            Status;
    00502     OBJECT_ATTRIBUTES  *OriginalAttributes;
    00503     OBJECT_ATTRIBUTES  *NormalFile;
    00504     OBJECT_ATTRIBUTES   RestrictedFileAttributes;
    00505     OBJECT_ATTRIBUTES  *RestrictedFile = &RestrictedFileAttributes;
    00506     UNICODE_STRING      RestrictedObjectName;
    00507
    00508     FILE_BASIC_INFORMATION  BasicInfo;
    00509
    00510 //NTSTATUS st;
    00511
    00512     if (!IsRestricted())
    00513         return CALL_OPEN(ObjectAttributes);
    00514
    00515     //
    00516     // Check to see if this file is mappable.  If not don't try
    00517     //
    00518
    00519     NormalFile = ObjectAttributes;
    00520
    00521     CopyMemory(RestrictedFile, NormalFile, sizeof(OBJECT_ATTRIBUTES));
    00522     RestrictedFile->ObjectName = &RestrictedObjectName;
    00523
    00524     if (!IsInterestingPath(NormalFile, RestrictedFile))
    00525         return CALL_OPEN(NormalFile);
    00526
    00527     //
    00528     // The file/directory is mappable
    00529     //
    00530
    00531     if (OpenOptions & FILE_DIRECTORY_FILE)
    00532     {
    00533         //
    00534         // This is a directory, attempt to access the given one, if that fails
    00535         // try to access the shadowed version
    00536         //
    00537
    00538         Status = CALL_OPEN(NormalFile);
    00539
    00540         if (!NT_SUCCESS(Status))
    00541         {
    00542             Status = CALL_OPEN(RestrictedFile);
    00543         }
    00544     }
    00545     else
    00546     {
    00547         //
    00548         // This is a file (not a directory).  Attempt to open the shadowed
    00549         // version.  If that fails, attempt to open the real version.  If that
    00550         // fails with access denied, then try to copy the file to the shadow
    00551         // area and try to open it there again.
    00552         //
    00553
    00554         Status = CALL_OPEN(RestrictedFile);
    00555
    00556         if (!NT_SUCCESS(Status))
    00557         {
    00558             Status = CALL_OPEN(NormalFile);
    00559
    00560             if (!NT_SUCCESS(Status))
    00561             {
    00562                 Status = CopyRestrictedFile(NormalFile, RestrictedFile);
    00563
    00564                 if (NT_SUCCESS(Status))
    00565                 {
    00566                     Status = CALL_OPEN(RestrictedFile);
    00567                 }
    00568             }
    00569         }
    00570     }
    00571 /*
    00572 if (!NT_SUCCESS(Status))
    00573   DbgPrint("  Failed %wZ\n", NormalFile->ObjectName);
    00574 */
    00575     RtlFreeHeap(RtlProcessHeap(), 0, RestrictedObjectName.Buffer);
    00576
    00577     return Status;
    00578
    00579 #undef CALL_OPEN
    00580 }
    NTSTATUS

NTSTATUS NtQueryAttributesFile | ( | IN POBJECT_ATTRIBUTES | ObjectAttributes,
|  | OUT PFILE_BASIC_INFORMATION | FileInformation
| ) |

Definition at line 663 of file restrfil.c.

References IsInterestingPath(), IsRestricted(), NT_SUCCESS, NTSTATUS(), NtUnRestrictedQueryAttributesFile(), ObjectAttributes, RtlFreeHeap, and Status.

    00669                    :
    00670
    00671     Attempt to query the shadowed version of the given file.  If that fails
    00672     attempt to query the real version of the file
    00673
    00674 Arguments:
    00675
    00676     ObjectAttributes - Supplies the attributes to be used for file object (name,
    00677         SECURITY_DESCRIPTOR, etc.)
    00678
    00679     FileInformation - Supplies an output buffer to receive the returned file
    00680         attributes information.
    00681
    00682 Return Value:
    00683
    00684     The status returned is the final completion status of the operation.
    00685
    00686 --*/
    00687 {
    00688     NTSTATUS            Status;
    00689     OBJECT_ATTRIBUTES  *NormalFile;
    00690     OBJECT_ATTRIBUTES   RestrictedFileAttributes;
    00691     OBJECT_ATTRIBUTES  *RestrictedFile = &RestrictedFileAttributes;
    00692     UNICODE_STRING      RestrictedObjectName;
    00693
    00694     if (!IsRestricted())
    00695         return NtUnRestrictedQueryAttributesFile(
    00696                         ObjectAttributes,
    00697                         FileInformation);
    00698
    00699     //
    00700     // Check to see if this file is mappable.  Map it if it is
    00701     //
    00702
    00703     NormalFile = ObjectAttributes;
    00704
    00705     CopyMemory(RestrictedFile, NormalFile, sizeof(OBJECT_ATTRIBUTES));
    00706     RestrictedFile->ObjectName = &RestrictedObjectName;
    00707
    00708     if (IsInterestingPath(NormalFile, RestrictedFile))
    00709     {
    00710         Status = NtUnRestrictedQueryAttributesFile(
    00711                         RestrictedFile,
    00712                         FileInformation);
    00713
    00714         RtlFreeHeap(RtlProcessHeap(), 0, RestrictedObjectName.Buffer);
    00715
    00716         if (NT_SUCCESS(Status) || STATUS_ACCESS_DENIED == Status)
    00717             return Status;
    00718     }
    00719
    00720     //
    00721     // The file is not mappable or accessing the mapped version failed.
    00722     //
    00723
    00724     return NtUnRestrictedQueryAttributesFile(
    00725                     NormalFile,
    00726                     FileInformation);
    00727 }
    NTSTATUS

NTSTATUS NtSetInformationFile | ( | IN HANDLE | FileHandle,
|  | OUT PIO_STATUS_BLOCK | IoStatusBlock,
|  | IN PVOID | FileInformation,
|  | IN ULONG | Length,
|  | IN FILE_INFORMATION_CLASS | FileInformationClass
| ) |

Definition at line 740 of file restrfil.c.

References IsInterestingPath(), IsRestricted(), NT_SUCCESS, NTSTATUS(), NtUnRestrictedSetInformationFile(), NULL, RtlAllocateHeap, RtlFreeHeap, Status, and USHORT.

Referenced by SepClientOpenPipe().

    00749                    :
    00750
    00751     Hook NtSetInformationFile to catch renames/moves of files by restricted
    00752     processes.
    00753
    00754 Arguments:
    00755
    00756     FileHandle - Supplies a handle to the file whose information should be
    00757         changed.
    00758
    00759     IoStatusBlock - Address of the caller's I/O status block.
    00760
    00761     FileInformation - Supplies a buffer containing the information which should
    00762         be changed on the file.
    00763
    00764     Length - Supplies the length, in bytes, of the FileInformation buffer.
    00765
    00766     FileInformationClass - Specifies the type of information which should be
    00767         changed about the file.
    00768
    00769 Return Value:
    00770
    00771     The status returned is the final completion status of the operation.
    00772
    00773 --*/
    00774 {
    00775     NTSTATUS            Status;
    00776     OBJECT_ATTRIBUTES   NormalFileAttributes;
    00777     OBJECT_ATTRIBUTES  *NormalFile = &NormalFileAttributes;
    00778     UNICODE_STRING      NormalFileName;
    00779     OBJECT_ATTRIBUTES   RestrictedFileAttributes;
    00780     OBJECT_ATTRIBUTES  *RestrictedFile = &RestrictedFileAttributes;
    00781     UNICODE_STRING      RestrictedObjectName;
    00782
    00783     FILE_RENAME_INFORMATION *RenameInfo;
    00784
    00785     //
    00786     // Try the original operation first
    00787     //
    00788
    00789     Status = NtUnRestrictedSetInformationFile(
    00790                         FileHandle,
    00791                         IoStatusBlock,
    00792                         FileInformation,
    00793                         Length,
    00794                         FileInformationClass);
    00795
    00796     if (NT_SUCCESS(Status)
    00797         || !IsRestricted()
    00798         || FileRenameInformation != FileInformationClass)
    00799     {
    00800         return Status;
    00801     }
    00802
    00803     //
    00804     // Check to see if this file is mappable.  Map it if it is
    00805     //
    00806
    00807     RenameInfo = (FILE_RENAME_INFORMATION *) FileInformation;
    00808
    00809     NormalFileName.MaximumLength = (USHORT) RenameInfo->FileNameLength;
    00810     NormalFileName.Length        = (USHORT) RenameInfo->FileNameLength;
    00811     NormalFileName.Buffer        = RenameInfo->FileName;
    00812
    00813     InitializeObjectAttributes(
    00814             NormalFile,
    00815             &NormalFileName,
    00816             OBJ_CASE_INSENSITIVE,
    00817             RenameInfo->RootDirectory,
    00818             NULL);
    00819
    00820     CopyMemory(RestrictedFile, NormalFile, sizeof(OBJECT_ATTRIBUTES));
    00821     RestrictedFile->ObjectName = &RestrictedObjectName;
    00822
    00823     if (IsInterestingPath(NormalFile, RestrictedFile))
    00824     {
    00825         FILE_RENAME_INFORMATION *NewRenameInfo;
    00826         NTSTATUS                 Status2;
    00827
    00828         NewRenameInfo = RtlAllocateHeap(
    00829                             RtlProcessHeap(),
    00830                             0,
    00831                             sizeof(*RenameInfo) + RestrictedObjectName.Length);
    00832
    00833         if (NULL != RenameInfo)
    00834         {
    00835             NewRenameInfo->ReplaceIfExists = RenameInfo->ReplaceIfExists;
    00836             NewRenameInfo->RootDirectory   = NULL;
    00837             NewRenameInfo->FileNameLength  = RestrictedObjectName.Length;
    00838             CopyMemory(
    00839                     NewRenameInfo->FileName,
    00840                     RestrictedObjectName.Buffer,
    00841                     RestrictedObjectName.Length);
    00842
    00843             Status2 = NtUnRestrictedSetInformationFile(
    00844                                 FileHandle,
    00845                                 IoStatusBlock,
    00846                                 NewRenameInfo,
    00847                                 sizeof(*RenameInfo) + RestrictedObjectName.Length,
    00848                                 FileInformationClass);
    00849
    00850             Status = NT_SUCCESS(Status2) ? Status2 : Status;
    00851
    00852             RtlFreeHeap(RtlProcessHeap(), 0, NewRenameInfo);
    00853         }
    00854
    00855         RtlFreeHeap(RtlProcessHeap(), 0, RestrictedObjectName.Buffer);
    00856     }
    00857
    00858     return Status;
    00859 }
    NTSTATUS

NTSTATUS NtUnRestrictedCreateFile | ( | OUT PHANDLE | FileHandle,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN POBJECT_ATTRIBUTES | ObjectAttributes,
|  | OUT PIO_STATUS_BLOCK | IoStatusBlock,
|  | IN PLARGE_INTEGER AllocationSize | OPTIONAL,
|  | IN ULONG | FileAttributes,
|  | IN ULONG | ShareAccess,
|  | IN ULONG | CreateDisposition,
|  | IN ULONG | CreateOptions,
|  | IN PVOID EaBuffer | OPTIONAL,
|  | IN ULONG | EaLength
| ) |

| Referenced by CopyRestrictedFile(), CopyStream(), and CreateDirectories().

NTSTATUS NtUnRestrictedDeleteFile | ( | IN POBJECT_ATTRIBUTES | ObjectAttributes | ) |

| Referenced by CopyRestrictedFile(), and NtDeleteFile().

NTSTATUS NtUnRestrictedOpenFile | ( | OUT PHANDLE | FileHandle,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN POBJECT_ATTRIBUTES | ObjectAttributes,
|  | OUT PIO_STATUS_BLOCK | IoStatusBlock,
|  | IN ULONG | ShareAccess,
|  | IN ULONG | OpenOptions
| ) |

| Referenced by CopyRestrictedFile(), CopyStream(), and InitializeRestrictedStuff().

NTSTATUS NtUnRestrictedQueryAttributesFile | ( | IN POBJECT_ATTRIBUTES | ObjectAttributes,
|  | OUT PFILE_BASIC_INFORMATION | FileInformation
| ) |

| Referenced by CopyRestrictedFile(), and NtQueryAttributesFile().

NTSTATUS NtUnRestrictedSetInformationFile | ( | IN HANDLE | FileHandle,
|  | OUT PIO_STATUS_BLOCK | IoStatusBlock,
|  | IN PVOID | FileInformation,
|  | IN ULONG | Length,
|  | IN FILE_INFORMATION_CLASS | FileInformationClass
| ) |

| Referenced by NtSetInformationFile().

NTSTATUS ZwCreateFile | ( | OUT PHANDLE | FileHandle,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN POBJECT_ATTRIBUTES | ObjectAttributes,
|  | OUT PIO_STATUS_BLOCK | IoStatusBlock,
|  | IN PLARGE_INTEGER AllocationSize | OPTIONAL,
|  | IN ULONG | FileAttributes,
|  | IN ULONG | ShareAccess,
|  | IN ULONG | CreateDisposition,
|  | IN ULONG | CreateOptions,
|  | IN PVOID EaBuffer | OPTIONAL,
|  | IN ULONG | EaLength
| ) |

Definition at line 418 of file restrfil.c.

References FileAttributes, NtCreateFile(), and ObjectAttributes.

Referenced by CmpOpenFileWithExtremePrejudice(), CmpOpenHiveFiles(), FsRecCreateAndRegisterDO(), FsRtlpOpenDev(), IoepGetErrCaseDB(), IopBootLogToFile(), OpenDevice(), and UserBeep().

    00431 {
    00432     return NtCreateFile(
    00433                     FileHandle,
    00434                     DesiredAccess,
    00435                     ObjectAttributes,
    00436                     IoStatusBlock,
    00437                     AllocationSize,
    00438                     FileAttributes,
    00439                     ShareAccess,
    00440                     CreateDisposition,
    00441                     CreateOptions,
    00442                     EaBuffer,
    00443                     EaLength);
    00444 }

NTSTATUS ZwDeleteFile | ( | IN POBJECT_ATTRIBUTES | ObjectAttributes | ) |

Definition at line 655 of file restrfil.c.

References NtDeleteFile(), NTSTATUS(), and ObjectAttributes.

    00656 {
    00657     return NtDeleteFile(ObjectAttributes);
    00658 }

NTSTATUS ZwOpenFile | ( | OUT PHANDLE | FileHandle,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN POBJECT_ATTRIBUTES | ObjectAttributes,
|  | OUT PIO_STATUS_BLOCK | IoStatusBlock,
|  | IN ULONG | ShareAccess,
|  | IN ULONG | OpenOptions
| ) |

Definition at line 582 of file restrfil.c.

References NtOpenFile(), and ObjectAttributes.

Referenced by CmpOpenFileWithExtremePrejudice(), DbgkCreateThread(), DbgkpSectionHandleToFileHandle(), GetNextReparseVolumePath(), IoAttachDevice(), IoGetDeviceObjectPointer(), IopApplySystemPartitionProt(), IopGetDumpStack(), IopMarkBootPartition(), MiLoadSystemImage(), OpenDeviceReparseIndex(), PsLocateSystemDll(), QueryDeviceNameForPath(), RtlpOpenImageFile(), and xHalIoAssignDriveLetters().

    00590 {
    00591     return NtOpenFile(
    00592                 FileHandle,
    00593                 DesiredAccess,
    00594                 ObjectAttributes,
    00595                 IoStatusBlock,
    00596                 ShareAccess,
    00597                 OpenOptions);
    00598 }

NTSTATUS ZwQueryAttributesFile | ( | IN POBJECT_ATTRIBUTES | ObjectAttributes,
|  | OUT PFILE_BASIC_INFORMATION | FileInformation
| ) |

Definition at line 729 of file restrfil.c.

References NtQueryAttributesFile(), and ObjectAttributes.

Referenced by CmpOpenFileWithExtremePrejudice().

    00733 {
    00734     return NtQueryAttributesFile(ObjectAttributes, FileInformation);
    00735 }

NTSTATUS ZwSetInformationFile | ( | IN HANDLE | FileHandle,
|  | OUT PIO_STATUS_BLOCK | IoStatusBlock,
|  | IN PVOID | FileInformation,
|  | IN ULONG | Length,
|  | IN FILE_INFORMATION_CLASS | FileInformationClass
| ) |

Definition at line 861 of file restrfil.c.

References NtSetInformationFile().

Referenced by CmpDoFileSetSize(), CmpOpenFileWithExtremePrejudice(), CmpWorker(), and NtCreatePagingFile().

    00868 {
    00869     return NtSetInformationFile(
    00870                     FileHandle,
    00871                     IoStatusBlock,
    00872                     FileInformation,
    00873                     Length,
    00874                     FileInformationClass);
    00875 }

## Variable Documentation

enum { ... } Restricted

| Referenced by CheckRestricted(), IsRestricted(), SepMaximumAccessCheck(), SepNormalAccessCheck(), and SepSidInTokenEx().

UNICODE_STRING SiteDirectory = {0, 0, 0}

| Definition at line 124 of file restrfil.c. Referenced by CreateDirectories(), InitializeRestrictedStuff(), and IsInterestingPath().

UNICODE_STRING SystemPath1 = {0, 0, 0}

| Definition at line 121 of file restrfil.c. Referenced by InitializeRestrictedStuff(), and IsInterestingPath().

UNICODE_STRING SystemPath2 = {0, 0, 0}

| Definition at line 122 of file restrfil.c. Referenced by InitializeRestrictedStuff(), and IsInterestingPath().

UNICODE_STRING SystemPath3 = {0, 0, 0}

| Definition at line 123 of file restrfil.c. Referenced by InitializeRestrictedStuff(), and IsInterestingPath().