00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include <nt.h>
00027
#include <ntdef.h>
00028
#include <ntrtl.h>
00029
#include <nturtl.h>
00030
#include <windef.h>
00031
00032
00033
00034
00035
00036
00037 #define GetSiteSidFromToken xxxGetSiteSidFromToken
00038 #define GetMangledSiteSid xxxGetMangledSiteSid
00039 #define IsTokenRestricted xxxIsTokenRestricted
00040
#include <winbase.h>
00041
#undef GetSiteSidFromToken
00042
#undef GetMangledSiteSid
00043
#undef IsTokenRestricted
00044
00045
00046
void Base32Encode(LPVOID pvData, UINT cbData, LPWSTR pchData);
00047 HRESULT
GetMangledSiteSid(PSID pSid, ULONG cchMangledSite, LPWSTR *ppwszMangledSite);
00048 PSID
GetSiteSidFromToken(IN HANDLE TokenHandle);
00049
BOOL IsTokenRestricted(IN HANDLE TokenHandle);
00050
00051
00052
00053
00054
00055
00056
00057
BOOL IsInterestingPath(
00058 OBJECT_ATTRIBUTES *NormalFile,
00059 OBJECT_ATTRIBUTES *RestrictedFile);
00060
NTSTATUS CopyRestrictedFile(
00061 OBJECT_ATTRIBUTES *SourceAttributes,
00062 OBJECT_ATTRIBUTES *DestinationAttributes);
00063
NTSTATUS CreateDirectories(OBJECT_ATTRIBUTES *Attributes);
00064
BOOL FileExists(OBJECT_ATTRIBUTES *Attributes);
00065
NTSTATUS CopyStream(
00066 HANDLE SourceFile,
00067 HANDLE DestinationFile,
00068 FILE_STREAM_INFORMATION *StreamInfo,
00069 BYTE *Buffer,
00070 ULONG BufferSize);
00071
NTSTATUS InitializeRestrictedStuff();
00072
00073
00074
00075
00076
00077
NTSTATUS NtUnRestrictedCreateFile(
00078 OUT PHANDLE FileHandle,
00079 IN ACCESS_MASK DesiredAccess,
00080 IN POBJECT_ATTRIBUTES ObjectAttributes,
00081 OUT PIO_STATUS_BLOCK IoStatusBlock,
00082 IN PLARGE_INTEGER AllocationSize OPTIONAL,
00083 IN ULONG FileAttributes,
00084 IN ULONG ShareAccess,
00085 IN ULONG CreateDisposition,
00086 IN ULONG CreateOptions,
00087 IN PVOID EaBuffer OPTIONAL,
00088 IN ULONG EaLength);
00089
00090
NTSTATUS NtUnRestrictedOpenFile(
00091 OUT PHANDLE FileHandle,
00092 IN ACCESS_MASK DesiredAccess,
00093 IN POBJECT_ATTRIBUTES ObjectAttributes,
00094 OUT PIO_STATUS_BLOCK IoStatusBlock,
00095 IN ULONG ShareAccess,
00096 IN ULONG OpenOptions);
00097
NTSTATUS NtUnRestrictedDeleteFile(
00098 IN POBJECT_ATTRIBUTES ObjectAttributes);
00099
NTSTATUS NtUnRestrictedQueryAttributesFile(
00100 IN POBJECT_ATTRIBUTES ObjectAttributes,
00101 OUT PFILE_BASIC_INFORMATION FileInformation);
00102
NTSTATUS NtUnRestrictedSetInformationFile(
00103 IN HANDLE FileHandle,
00104 OUT PIO_STATUS_BLOCK IoStatusBlock,
00105 IN PVOID FileInformation,
00106 IN ULONG Length,
00107 IN FILE_INFORMATION_CLASS FileInformationClass);
00108
00109
00110
00111
00112
00113
enum
00114 {
00115
eUnRestricted = 0,
00116
eRestricted,
00117
eUnknownRestricted
00118 }
00119
Restricted =
eUnknownRestricted;
00120
00121 UNICODE_STRING
SystemPath1 = {0, 0, 0};
00122 UNICODE_STRING
SystemPath2 = {0, 0, 0};
00123 UNICODE_STRING
SystemPath3 = {0, 0, 0};
00124 UNICODE_STRING
SiteDirectory = {0, 0, 0};
00125
00126
00127
00128
void
00129 CheckRestricted()
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
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
00159
00160
00161
Restricted =
eUnRestricted;
00162
00163
00164
00165
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 }
00218
00219
00220
00221 __inline
00222
BOOL
00223 IsRestricted()
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 {
00241
if (
eUnRestricted ==
Restricted)
00242
return FALSE;
00243
00244
if (
eUnknownRestricted ==
Restricted)
00245
CheckRestricted();
00246
00247
return (
eRestricted ==
Restricted);
00248 }
00249
00250
00251
00252
NTSTATUS
00253 NtCreateFile(
00254 OUT PHANDLE FileHandle,
00255 IN ACCESS_MASK DesiredAccess,
00256 IN POBJECT_ATTRIBUTES ObjectAttributes,
00257 OUT PIO_STATUS_BLOCK IoStatusBlock,
00258 IN PLARGE_INTEGER AllocationSize OPTIONAL,
00259 IN ULONG FileAttributes,
00260 IN ULONG ShareAccess,
00261 IN ULONG CreateDisposition,
00262 IN ULONG CreateOptions,
00263 IN PVOID EaBuffer OPTIONAL,
00264 IN ULONG EaLength
00265 )
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
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
00324
00325
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
00338
00339
if (!
IsRestricted())
00340
return CALL_CREATE(
ObjectAttributes);
00341
00342
00343
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
00356
00357
00358
00359
00360
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
00374
00375
00376
else if (
FileExists(RestrictedFile))
00377 {
00378
Status =
CALL_CREATE(RestrictedFile);
00379 }
00380
00381
00382
00383
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
00409
00410
00411
RtlFreeHeap(RtlProcessHeap(), 0, RestrictedObjectName.Buffer);
00412
00413
return Status;
00414
00415
#undef CALL_CREATE
00416
}
00417
NTSTATUS
00418 ZwCreateFile(
00419 OUT PHANDLE FileHandle,
00420 IN ACCESS_MASK DesiredAccess,
00421 IN POBJECT_ATTRIBUTES ObjectAttributes,
00422 OUT PIO_STATUS_BLOCK IoStatusBlock,
00423 IN PLARGE_INTEGER AllocationSize OPTIONAL,
00424 IN ULONG FileAttributes,
00425 IN ULONG ShareAccess,
00426 IN ULONG CreateDisposition,
00427 IN ULONG CreateOptions,
00428 IN PVOID EaBuffer OPTIONAL,
00429 IN ULONG EaLength
00430 )
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 }
00445
00446
00447
00448
NTSTATUS
00449 NtOpenFile(
00450 OUT PHANDLE FileHandle,
00451 IN ACCESS_MASK DesiredAccess,
00452 IN POBJECT_ATTRIBUTES ObjectAttributes,
00453 OUT PIO_STATUS_BLOCK IoStatusBlock,
00454 IN ULONG ShareAccess,
00455 IN ULONG OpenOptions
00456 )
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 {
00487
#define CALL_OPEN(object) \
00488
NtUnRestrictedOpenFile( \
00489
FileHandle, \
00490
DesiredAccess, \
00491
object, \
00492
IoStatusBlock, \
00493
ShareAccess, \
00494
OpenOptions)
00495
00496
00497
00498
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
00511
00512
if (!
IsRestricted())
00513
return CALL_OPEN(
ObjectAttributes);
00514
00515
00516
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
00529
00530
00531
if (OpenOptions & FILE_DIRECTORY_FILE)
00532 {
00533
00534
00535
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
00549
00550
00551
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
00573
00574
00575
RtlFreeHeap(RtlProcessHeap(), 0, RestrictedObjectName.Buffer);
00576
00577
return Status;
00578
00579
#undef CALL_OPEN
00580
}
00581
NTSTATUS
00582 ZwOpenFile(
00583 OUT PHANDLE FileHandle,
00584 IN ACCESS_MASK DesiredAccess,
00585 IN POBJECT_ATTRIBUTES ObjectAttributes,
00586 OUT PIO_STATUS_BLOCK IoStatusBlock,
00587 IN ULONG ShareAccess,
00588 IN ULONG OpenOptions
00589 )
00590 {
00591
return NtOpenFile(
00592 FileHandle,
00593 DesiredAccess,
00594
ObjectAttributes,
00595 IoStatusBlock,
00596 ShareAccess,
00597 OpenOptions);
00598 }
00599
00600
00601
00602 NTSTATUS NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
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
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
00651
00652
00653
return NtUnRestrictedDeleteFile(NormalFile);
00654 }
00655 NTSTATUS ZwDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
00656 {
00657
return NtDeleteFile(
ObjectAttributes);
00658 }
00659
00660
00661
00662
NTSTATUS
00663 NtQueryAttributesFile(
00664 IN POBJECT_ATTRIBUTES ObjectAttributes,
00665 OUT PFILE_BASIC_INFORMATION FileInformation
00666 )
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
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
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
00722
00723
00724
return NtUnRestrictedQueryAttributesFile(
00725 NormalFile,
00726 FileInformation);
00727 }
00728
NTSTATUS
00729 ZwQueryAttributesFile(
00730 IN POBJECT_ATTRIBUTES ObjectAttributes,
00731 OUT PFILE_BASIC_INFORMATION FileInformation
00732 )
00733 {
00734
return NtQueryAttributesFile(
ObjectAttributes, FileInformation);
00735 }
00736
00737
00738
00739
NTSTATUS
00740 NtSetInformationFile(
00741 IN HANDLE FileHandle,
00742 OUT PIO_STATUS_BLOCK IoStatusBlock,
00743 IN PVOID FileInformation,
00744 IN ULONG Length,
00745 IN FILE_INFORMATION_CLASS FileInformationClass
00746 )
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
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
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
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 }
00860
NTSTATUS
00861 ZwSetInformationFile(
00862 IN HANDLE FileHandle,
00863 OUT PIO_STATUS_BLOCK IoStatusBlock,
00864 IN PVOID FileInformation,
00865 IN ULONG Length,
00866 IN FILE_INFORMATION_CLASS FileInformationClass
00867 )
00868 {
00869
return NtSetInformationFile(
00870 FileHandle,
00871 IoStatusBlock,
00872 FileInformation,
00873 Length,
00874 FileInformationClass);
00875 }
00876
00877
00878
00879 NTSTATUS InitializeRestrictedStuff()
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
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
00923
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
00963
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
00980
00981
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
00995
00996
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
01010
01011
01012
01013
01014
01015
01016
01017
01018
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
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
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
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
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
01116
01117 Path.Length -=
sizeof(
L'\0');
01118
01119
01120
01121 Path.Length -= 2 *
sizeof(WCHAR);
01122 MoveMemory(Path.Buffer, Path.Buffer + 2, Path.Length);
01123
01124
01125
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
01155
01156
Initialized =
NT_SUCCESS(
Status);
01157
01158
return Status;
01159 }
01160
01161
01162
01163 BOOL IsInterestingPath(
01164 IN POBJECT_ATTRIBUTES NormalFile,
01165 IN OUT POBJECT_ATTRIBUTES RestrictedFile)
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
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
01193
01194
01195
if (
NULL != NormalFile->RootDirectory)
01196 {
01197 WCHAR LastChar;
01198
01199
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
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
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
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
01267
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
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 }
01308
01309
01310
01311 NTSTATUS CreateDirectories(OBJECT_ATTRIBUTES *Attributes)
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
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
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
01360
01361
01362 SubDirectory.Buffer = Attributes->ObjectName->Buffer;
01363 NextDirectory = SubDirectory.Buffer;
01364 NextDirectory +=
SiteDirectory.Length /
sizeof(WCHAR);
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
do
01375 {
01376
01377
01378
do
01379 {
01380 ++NextDirectory;
01381 }
01382
while (NextDirectory < EndOfString &&
L'\\' != *NextDirectory);
01383
01384
if ( !(NextDirectory < EndOfString) )
01385
break;
01386
01387
01388
01389 SubDirectory.Length = (NextDirectory - SubDirectory.Buffer);
01390 SubDirectory.Length *=
sizeof(WCHAR);
01391 SubDirectory.MaximumLength = SubDirectory.Length;
01392
01393
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 }
01420
01421
01422
01423 BOOL FileExists(OBJECT_ATTRIBUTES *Attributes)
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440 {
01441
NTSTATUS Status;
01442 FILE_BASIC_INFORMATION FileInfo;
01443
01444
Status =
NtQueryAttributesFile(Attributes, &FileInfo);
01445
01446
return (STATUS_SUCCESS ==
Status);
01447 }
01448
01449
01450
01451 NTSTATUS CopyStream(
01452 HANDLE SourceFile,
01453 HANDLE DestinationFile,
01454 FILE_STREAM_INFORMATION *StreamInfo,
01455 BYTE *Buffer,
01456 ULONG BufferSize)
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
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
01492
01493
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
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 }
01593
01594
01595
01596 NTSTATUS CopyRestrictedFile(
01597 OBJECT_ATTRIBUTES *SourceAttributes,
01598 OBJECT_ATTRIBUTES *DestinationAttributes)
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
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
01640
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
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
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
01682
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
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
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
01742
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
01771
01772
01773
NtSetInformationFile(
01774 DestinationFile,
01775 &DestinationIoStatus,
01776 &BasicInfo,
01777
sizeof(BasicInfo),
01778 FileBasicInformation);
01779
01780
01781
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 }
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843 PSID
01844 GetSiteSidFromToken(
01845 IN HANDLE TokenHandle
01846 )
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
01864
return NULL;
01865 }
01866
01867 RestrictedSids = (PTOKEN_GROUPS)
RtlAllocateHeap(RtlProcessHeap(), 0, ReturnLength);
01868
if (RestrictedSids ==
NULL)
01869 {
01870
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
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
01908 }
01909
01910
RtlFreeHeap(RtlProcessHeap(), 0, RestrictedSids);
01911
return psSiteSid;
01912 }
01913
01914 HRESULT
01915 GetMangledSiteSid(PSID pSid, ULONG cchMangledSite, LPWSTR *ppwszMangledSite)
01916 {
01917
if (cchMangledSite < MAX_MANGLED_SITE)
01918 {
01919
01920
01921
01922
01923
return E_OUTOFMEMORY;
01924 }
01925
01926
01927
ASSERT(4 == *
RtlSubAuthorityCountSid(pSid));
01928
01929
Base32Encode(
01930
RtlSubAuthoritySid(pSid, 0),
01931 *
RtlSubAuthorityCountSid(pSid) *
sizeof(
DWORD),
01932 *ppwszMangledSite);
01933
01934
01935
ASSERT(MAX_MANGLED_SITE - 1 == wcslen(*ppwszMangledSite));
01936
01937
return S_OK;
01938 }
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953 void Base32Encode(LPVOID pvData, UINT cbData, LPWSTR pchData)
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;
01962 ULONG accum = 0;
01963 ULONG value;
01964
BYTE *pData = (
BYTE *) pvData;
01965
01966
01967
01968
while (cbData)
01969 {
01970
01971
01972 accum = (accum << 8) | *pData++;
01973 shift += 8;
01974 --cbData;
01975
01976
01977
01978
while ( shift >= 5 )
01979 {
01980 shift -= 5;
01981 value = (accum >> shift) & 0x1Fl;
01982
01983 *pchData++ = alphabet[value];
01984 }
01985 }
01986
01987
01988
01989
if (shift)
01990 {
01991 value = (accum << (5 - shift)) & 0x1Fl;
01992
01993 *pchData++ = alphabet[value];
01994 }
01995
01996 *pchData =
L'\0';
01997 }
01998
01999
02000
BOOL
02001 IsTokenRestricted(
02002 IN HANDLE TokenHandle
02003 )
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
02021
return(
FALSE);
02022 }
02023
02024 RestrictedSids = (PTOKEN_GROUPS)
RtlAllocateHeap(RtlProcessHeap(), 0, ReturnLength);
02025
if (RestrictedSids ==
NULL)
02026 {
02027
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
02048 }
02049
RtlFreeHeap(RtlProcessHeap(), 0, RestrictedSids);
02050
return(Result);
02051 }