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
#include "ntrtlp.h"
00026
#include <nturtl.h>
00027
#include <string.h>
00028
#include "init.h"
00029
#include "ntos.h"
00030 #define ROUND_UP( x, y ) ((ULONG)(x) + ((y)-1) & ~((y)-1))
00031
#ifdef KERNEL
00032
#define ISTERMINALSERVER() (SharedUserData->SuiteMask & (1 << TerminalServer))
00033
#else
00034 #define ISTERMINALSERVER() (USER_SHARED_DATA->SuiteMask & (1 << TerminalServer))
00035
#endif
00036
00037
VOID
00038
RtlpCopyProcString(
00039 IN OUT PWSTR *pDst,
00040 OUT PUNICODE_STRING DestString,
00041 IN PUNICODE_STRING SourceString,
00042 IN ULONG DstAlloc OPTIONAL
00043 );
00044
00045
NTSTATUS
00046
RtlpOpenImageFile(
00047 IN PUNICODE_STRING ImagePathName,
00048 IN ULONG Attributes,
00049 OUT PHANDLE FileHandle,
00050 IN BOOLEAN ReportErrors
00051 );
00052
00053
NTSTATUS
00054
RtlpFreeStack(
00055 IN HANDLE Process,
00056 IN PINITIAL_TEB InitialTeb
00057 );
00058
00059
NTSTATUS
00060
RtlpCreateStack(
00061 IN HANDLE Process,
00062 IN SIZE_T MaximumStackSize OPTIONAL,
00063 IN SIZE_T CommittedStackSize OPTIONAL,
00064 IN ULONG ZeroBits OPTIONAL,
00065 OUT PINITIAL_TEB InitialTeb
00066 );
00067
00068
#if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
00069
#pragma alloc_text(INIT,RtlpCopyProcString )
00070
#pragma alloc_text(INIT,RtlCreateProcessParameters )
00071
#pragma alloc_text(INIT,RtlDestroyProcessParameters )
00072
#pragma alloc_text(INIT,RtlNormalizeProcessParams )
00073
#pragma alloc_text(INIT,RtlDeNormalizeProcessParams )
00074
#pragma alloc_text(INIT,RtlpOpenImageFile )
00075
#pragma alloc_text(INIT,RtlpCreateStack )
00076
#pragma alloc_text(INIT,RtlpFreeStack )
00077
#pragma alloc_text(INIT,RtlCreateUserProcess )
00078
#pragma alloc_text(INIT,RtlCreateUserThread )
00079
#endif
00080
00081
00082
VOID
00083 RtlpCopyProcString(
00084 IN OUT PWSTR *pDst,
00085 OUT PUNICODE_STRING DestString,
00086 IN PUNICODE_STRING SourceString,
00087 IN ULONG DstAlloc OPTIONAL
00088 )
00089 {
00090
if (!ARGUMENT_PRESENT( (ULONG_PTR)DstAlloc )) {
00091 DstAlloc =
SourceString->MaximumLength;
00092 }
00093
00094
if (
SourceString->Buffer !=
NULL &&
SourceString->Length != 0) {
00095 RtlMoveMemory( *pDst,
00096
SourceString->Buffer,
00097
SourceString->Length
00098 );
00099 }
00100
00101
DestString->Buffer = *pDst;
00102
DestString->Length =
SourceString->Length;
00103
DestString->MaximumLength = (
USHORT)DstAlloc;
00104
00105 *pDst = (PWSTR)((PCHAR)(*pDst) +
ROUND_UP( DstAlloc,
sizeof( ULONG ) ) );
00106
return;
00107 }
00108
00109
NTSTATUS
00110 RtlCreateProcessParameters(
00111 OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
00112 IN PUNICODE_STRING ImagePathName,
00113 IN PUNICODE_STRING DllPath OPTIONAL,
00114 IN PUNICODE_STRING CurrentDirectory OPTIONAL,
00115 IN PUNICODE_STRING CommandLine OPTIONAL,
00116 IN PVOID Environment OPTIONAL,
00117 IN PUNICODE_STRING WindowTitle OPTIONAL,
00118 IN PUNICODE_STRING DesktopInfo OPTIONAL,
00119 IN PUNICODE_STRING ShellInfo OPTIONAL,
00120 IN PUNICODE_STRING RuntimeData OPTIONAL
00121 )
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 {
00206 PRTL_USER_PROCESS_PARAMETERS p;
00207
NTSTATUS Status;
00208 UNICODE_STRING NullString = {0, 1,
L""};
00209 ULONG ByteCount;
00210 SIZE_T MaxByteCount;
00211 PWSTR pDst;
00212 PPEB Peb = NtCurrentPeb();
00213 HANDLE CurDirHandle;
00214
00215
00216
00217
00218
00219
00220
RtlAcquirePebLock();
00221
Status = STATUS_SUCCESS;
00222 p =
NULL;
00223 CurDirHandle =
NULL;
00224
try {
00225
00226
00227
00228
00229
00230
00231
if (!ARGUMENT_PRESENT( DllPath )) {
00232 DllPath = &Peb->ProcessParameters->DllPath;
00233 }
00234
00235
if (!ARGUMENT_PRESENT(
CurrentDirectory )) {
00236
00237
if ( Peb->ProcessParameters->CurrentDirectory.Handle ) {
00238 CurDirHandle = (HANDLE)((ULONG_PTR)Peb->ProcessParameters->CurrentDirectory.Handle & ~OBJ_HANDLE_TAGBITS);
00239 CurDirHandle = (HANDLE)((ULONG_PTR)CurDirHandle | RTL_USER_PROC_CURDIR_INHERIT);
00240 }
00241
CurrentDirectory = &Peb->ProcessParameters->CurrentDirectory.DosPath;
00242 }
00243
else {
00244
if ( Peb->ProcessParameters->CurrentDirectory.Handle ) {
00245 CurDirHandle = (HANDLE)((ULONG_PTR)Peb->ProcessParameters->CurrentDirectory.Handle & ~OBJ_HANDLE_TAGBITS);
00246 CurDirHandle = (HANDLE)((ULONG_PTR)CurDirHandle | RTL_USER_PROC_CURDIR_CLOSE);
00247 }
00248 }
00249
00250
if (!ARGUMENT_PRESENT(
CommandLine )) {
00251
CommandLine = ImagePathName;
00252 }
00253
00254
if (!ARGUMENT_PRESENT( Environment )) {
00255 Environment = Peb->ProcessParameters->Environment;
00256 }
00257
00258
if (!ARGUMENT_PRESENT( WindowTitle )) {
00259 WindowTitle = &NullString;
00260 }
00261
00262
if (!ARGUMENT_PRESENT( DesktopInfo )) {
00263 DesktopInfo = &NullString;
00264 }
00265
00266
if (!ARGUMENT_PRESENT( ShellInfo )) {
00267 ShellInfo = &NullString;
00268 }
00269
00270
if (!ARGUMENT_PRESENT( RuntimeData )) {
00271 RuntimeData = &NullString;
00272 }
00273
00274
00275
00276
00277
00278
00279
00280 ByteCount =
sizeof( **ProcessParameters );
00281 ByteCount +=
ROUND_UP( ImagePathName->Length +
sizeof(UNICODE_NULL),
sizeof( ULONG ) );
00282 ByteCount +=
ROUND_UP( DllPath->MaximumLength,
sizeof( ULONG ) );
00283 ByteCount +=
ROUND_UP( DOS_MAX_PATH_LENGTH*2,
sizeof( ULONG ) );
00284 ByteCount +=
ROUND_UP(
CommandLine->Length +
sizeof(UNICODE_NULL),
sizeof( ULONG ) );
00285 ByteCount +=
ROUND_UP( WindowTitle->MaximumLength,
sizeof( ULONG ) );
00286 ByteCount +=
ROUND_UP( DesktopInfo->MaximumLength,
sizeof( ULONG ) );
00287 ByteCount +=
ROUND_UP( ShellInfo->MaximumLength,
sizeof( ULONG ) );
00288 ByteCount +=
ROUND_UP( RuntimeData->MaximumLength,
sizeof( ULONG ) );
00289
00290
00291
00292
00293
00294 MaxByteCount = ByteCount;
00295
Status = ZwAllocateVirtualMemory( NtCurrentProcess(),
00296 (PVOID *)&p,
00297 0,
00298 &MaxByteCount,
00299 MEM_COMMIT,
00300 PAGE_READWRITE
00301 );
00302
if (!
NT_SUCCESS(
Status )) {
00303
return(
Status );
00304 }
00305
00306 p->MaximumLength = (ULONG) MaxByteCount;
00307 p->Length = ByteCount;
00308 p->Flags = RTL_USER_PROC_PARAMS_NORMALIZED;
00309 p->Environment = Environment;
00310 p->CurrentDirectory.Handle = CurDirHandle;
00311
00312
00313
00314
00315
00316 p->ConsoleFlags = Peb->ProcessParameters->ConsoleFlags;
00317
00318 pDst = (PWSTR)(p + 1);
00319
RtlpCopyProcString( &pDst,
00320 &p->CurrentDirectory.DosPath,
00321
CurrentDirectory,
00322 DOS_MAX_PATH_LENGTH*2
00323 );
00324
00325
RtlpCopyProcString( &pDst, &p->DllPath, DllPath, 0 );
00326
RtlpCopyProcString( &pDst, &p->ImagePathName, ImagePathName, ImagePathName->Length +
sizeof(UNICODE_NULL) );
00327
if (
CommandLine->Length ==
CommandLine->MaximumLength) {
00328
RtlpCopyProcString( &pDst, &p->CommandLine,
CommandLine, 0 );
00329 }
00330
else {
00331
RtlpCopyProcString( &pDst, &p->CommandLine,
CommandLine,
CommandLine->Length +
sizeof(UNICODE_NULL) );
00332 }
00333
RtlpCopyProcString( &pDst, &p->WindowTitle, WindowTitle, 0 );
00334
RtlpCopyProcString( &pDst, &p->DesktopInfo, DesktopInfo, 0 );
00335
RtlpCopyProcString( &pDst, &p->ShellInfo, ShellInfo, 0 );
00336
if (RuntimeData->Length != 0) {
00337
RtlpCopyProcString( &pDst, &p->RuntimeData, RuntimeData, 0 );
00338 }
00339
else {
00340 p->RuntimeData.Buffer =
NULL;
00341 p->RuntimeData.Length = 0;
00342 p->RuntimeData.MaximumLength = 0;
00343 }
00344 *ProcessParameters =
RtlDeNormalizeProcessParams( p );
00345 p =
NULL;
00346 }
00347 finally {
00348
if (AbnormalTermination()) {
00349
Status = STATUS_ACCESS_VIOLATION;
00350 }
00351
00352
if (p !=
NULL) {
00353
RtlDestroyProcessParameters( p );
00354 }
00355
00356
RtlReleasePebLock();
00357 }
00358
00359
return(
Status );
00360 }
00361
00362
00363
00364
NTSTATUS
00365 RtlDestroyProcessParameters(
00366 IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters
00367 )
00368 {
00369
NTSTATUS Status;
00370 SIZE_T RegionSize;
00371
00372 RegionSize = 0;
00373
Status = ZwFreeVirtualMemory( NtCurrentProcess(),
00374 (PVOID *)&ProcessParameters,
00375 &RegionSize,
00376 MEM_RELEASE
00377 );
00378
00379
return(
Status );
00380 }
00381
00382
00383 #define RtlpNormalizeProcessParam( Base, p ) \
00384
if ((p) != NULL) { \
00385
(p) = (PWSTR)((PCHAR)(p) + (ULONG_PTR)(Base)); \
00386
} \
00387
00388 #define RtlpDeNormalizeProcessParam( Base, p ) \
00389
if ((p) != NULL) { \
00390
(p) = (PWSTR)((PCHAR)(p) - (ULONG_PTR)(Base)); \
00391
} \
00392
00393
00394 PRTL_USER_PROCESS_PARAMETERS
00395 RtlNormalizeProcessParams(
00396 IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters
00397 )
00398 {
00399
if (!ARGUMENT_PRESENT( ProcessParameters )) {
00400
return(
NULL );
00401 }
00402
00403
if (ProcessParameters->Flags & RTL_USER_PROC_PARAMS_NORMALIZED) {
00404
return( ProcessParameters );
00405 }
00406
00407
RtlpNormalizeProcessParam( ProcessParameters,
00408 ProcessParameters->CurrentDirectory.DosPath.Buffer
00409 );
00410
00411
RtlpNormalizeProcessParam( ProcessParameters,
00412 ProcessParameters->DllPath.Buffer
00413 );
00414
00415
RtlpNormalizeProcessParam( ProcessParameters,
00416 ProcessParameters->ImagePathName.Buffer
00417 );
00418
00419
RtlpNormalizeProcessParam( ProcessParameters,
00420 ProcessParameters->CommandLine.Buffer
00421 );
00422
00423
RtlpNormalizeProcessParam( ProcessParameters,
00424 ProcessParameters->WindowTitle.Buffer
00425 );
00426
00427
RtlpNormalizeProcessParam( ProcessParameters,
00428 ProcessParameters->DesktopInfo.Buffer
00429 );
00430
00431
RtlpNormalizeProcessParam( ProcessParameters,
00432 ProcessParameters->ShellInfo.Buffer
00433 );
00434
00435
RtlpNormalizeProcessParam( ProcessParameters,
00436 ProcessParameters->RuntimeData.Buffer
00437 );
00438 ProcessParameters->Flags |= RTL_USER_PROC_PARAMS_NORMALIZED;
00439
00440
return( ProcessParameters );
00441 }
00442
00443 PRTL_USER_PROCESS_PARAMETERS
00444 RtlDeNormalizeProcessParams(
00445 IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters
00446 )
00447 {
00448
if (!ARGUMENT_PRESENT( ProcessParameters )) {
00449
return(
NULL );
00450 }
00451
00452
if (!(ProcessParameters->Flags & RTL_USER_PROC_PARAMS_NORMALIZED)) {
00453
return( ProcessParameters );
00454 }
00455
00456
RtlpDeNormalizeProcessParam( ProcessParameters,
00457 ProcessParameters->CurrentDirectory.DosPath.Buffer
00458 );
00459
00460
RtlpDeNormalizeProcessParam( ProcessParameters,
00461 ProcessParameters->DllPath.Buffer
00462 );
00463
00464
RtlpDeNormalizeProcessParam( ProcessParameters,
00465 ProcessParameters->ImagePathName.Buffer
00466 );
00467
00468
RtlpDeNormalizeProcessParam( ProcessParameters,
00469 ProcessParameters->CommandLine.Buffer
00470 );
00471
00472
RtlpDeNormalizeProcessParam( ProcessParameters,
00473 ProcessParameters->WindowTitle.Buffer
00474 );
00475
00476
RtlpDeNormalizeProcessParam( ProcessParameters,
00477 ProcessParameters->DesktopInfo.Buffer
00478 );
00479
00480
RtlpDeNormalizeProcessParam( ProcessParameters,
00481 ProcessParameters->ShellInfo.Buffer
00482 );
00483
00484
RtlpDeNormalizeProcessParam( ProcessParameters,
00485 ProcessParameters->RuntimeData.Buffer
00486 );
00487
00488 ProcessParameters->Flags &= ~RTL_USER_PROC_PARAMS_NORMALIZED;
00489
return( ProcessParameters );
00490 }
00491
00492
NTSTATUS
00493 RtlpOpenImageFile(
00494 IN PUNICODE_STRING ImagePathName,
00495 IN ULONG Attributes,
00496 OUT PHANDLE FileHandle,
00497 IN BOOLEAN ReportErrors
00498 )
00499 {
00500
NTSTATUS Status;
00501 OBJECT_ATTRIBUTES
ObjectAttributes;
00502 HANDLE
File;
00503 IO_STATUS_BLOCK IoStatus;
00504
00505 *FileHandle =
NULL;
00506
00507 InitializeObjectAttributes( &
ObjectAttributes,
00508 ImagePathName,
00509 Attributes,
00510
NULL,
00511
NULL
00512 );
00513
Status =
ZwOpenFile( &
File,
00514 SYNCHRONIZE | FILE_EXECUTE,
00515 &
ObjectAttributes,
00516 &IoStatus,
00517 FILE_SHARE_READ | FILE_SHARE_DELETE,
00518 FILE_NON_DIRECTORY_FILE
00519 );
00520
00521
if (!
NT_SUCCESS(
Status )) {
00522
#if DBG
00523
if (ReportErrors) {
00524
DbgPrint(
"NTRTL: RtlpOpenImageFile - NtCreateFile( %wZ ) failed. Status == %X\n",
00525 ImagePathName,
00526
Status
00527 );
00528 }
00529
#endif // DBG
00530
return(
Status );
00531 }
00532
00533 *FileHandle =
File;
00534
return( STATUS_SUCCESS );
00535 }
00536
00537
00538
NTSTATUS
00539 RtlpCreateStack(
00540 IN HANDLE Process,
00541 IN SIZE_T MaximumStackSize OPTIONAL,
00542 IN SIZE_T CommittedStackSize OPTIONAL,
00543 IN ULONG ZeroBits OPTIONAL,
00544 OUT PINITIAL_TEB InitialTeb
00545 )
00546 {
00547
NTSTATUS Status;
00548 PCH Stack;
00549 SYSTEM_BASIC_INFORMATION SysInfo;
00550 BOOLEAN GuardPage;
00551 SIZE_T RegionSize;
00552 ULONG OldProtect;
00553
#if defined(_IA64_)
00554
PCH Bstore;
00555 SIZE_T CommittedBstoreSize;
00556 SIZE_T MaximumBstoreSize;
00557 SIZE_T MstackPlusBstoreSize;
00558
#endif
00559
00560
Status = ZwQuerySystemInformation( SystemBasicInformation,
00561 (PVOID)&SysInfo,
00562
sizeof( SysInfo ),
00563
NULL
00564 );
00565
if ( !
NT_SUCCESS(
Status ) ) {
00566
return(
Status );
00567 }
00568
00569
00570
00571
00572
00573
00574
if ( Process == NtCurrentProcess() ) {
00575 PPEB Peb;
00576 PIMAGE_NT_HEADERS NtHeaders;
00577
00578
00579 Peb = NtCurrentPeb();
00580 NtHeaders =
RtlImageNtHeader(Peb->ImageBaseAddress);
00581
00582
00583
if (!MaximumStackSize) {
00584 MaximumStackSize = NtHeaders->OptionalHeader.SizeOfStackReserve;
00585 }
00586
00587
if (!CommittedStackSize) {
00588 CommittedStackSize = NtHeaders->OptionalHeader.SizeOfStackCommit;
00589 }
00590
00591 }
00592
else {
00593
00594
if (!CommittedStackSize) {
00595 CommittedStackSize = SysInfo.PageSize;
00596 }
00597
00598
if (!MaximumStackSize) {
00599 MaximumStackSize = SysInfo.AllocationGranularity;
00600 }
00601
00602 }
00603
00604
00605
if ( CommittedStackSize >= MaximumStackSize ) {
00606 MaximumStackSize =
ROUND_UP(CommittedStackSize, (1024*1024));
00607 }
00608
00609
00610 CommittedStackSize =
ROUND_UP( CommittedStackSize, SysInfo.PageSize );
00611 MaximumStackSize =
ROUND_UP( MaximumStackSize,
00612 SysInfo.AllocationGranularity
00613 );
00614
00615 Stack =
NULL,
00616
00617
#if defined(_IA64_)
00618
00619
00620
00621
00622
00623 CommittedBstoreSize = CommittedStackSize;
00624 MaximumBstoreSize = MaximumStackSize;
00625 MstackPlusBstoreSize = MaximumBstoreSize + MaximumStackSize;
00626
00627
Status = ZwAllocateVirtualMemory( Process,
00628 (PVOID *)&Stack,
00629 ZeroBits,
00630 &MstackPlusBstoreSize,
00631 MEM_RESERVE,
00632 PAGE_READWRITE
00633 );
00634
#else
00635
00636
Status = ZwAllocateVirtualMemory( Process,
00637 (PVOID *)&Stack,
00638 ZeroBits,
00639 &MaximumStackSize,
00640 MEM_RESERVE,
00641 PAGE_READWRITE
00642 );
00643
#endif // defined(_IA64_)
00644
00645
if ( !
NT_SUCCESS(
Status ) ) {
00646
#if DBG
00647
DbgPrint(
"NTRTL: RtlpCreateStack( %lx ) failed. Stack Reservation Status == %X\n",
00648 Process,
00649
Status
00650 );
00651
#endif // DBG
00652
return(
Status );
00653 }
00654
00655
#if defined(_IA64_)
00656
InitialTeb->OldInitialTeb.OldBStoreLimit =
NULL;
00657
#endif // defined(_IA64_)
00658
00659
InitialTeb->OldInitialTeb.OldStackBase =
NULL;
00660
InitialTeb->OldInitialTeb.OldStackLimit =
NULL;
00661
InitialTeb->StackAllocationBase = Stack;
00662
InitialTeb->StackBase = Stack + MaximumStackSize;
00663
00664 Stack += MaximumStackSize - CommittedStackSize;
00665
if (MaximumStackSize > CommittedStackSize) {
00666 Stack -= SysInfo.PageSize;
00667 CommittedStackSize += SysInfo.PageSize;
00668 GuardPage =
TRUE;
00669 }
00670
else {
00671 GuardPage =
FALSE;
00672 }
00673
Status = ZwAllocateVirtualMemory( Process,
00674 (PVOID *)&Stack,
00675 0,
00676 &CommittedStackSize,
00677 MEM_COMMIT,
00678 PAGE_READWRITE
00679 );
00680
InitialTeb->StackLimit = Stack;
00681
00682
if ( !
NT_SUCCESS(
Status ) ) {
00683
#if DBG
00684
DbgPrint(
"NTRTL: RtlpCreateStack( %lx ) failed. Stack Commit Status == %X\n",
00685 Process,
00686
Status
00687 );
00688
#endif // DBG
00689
return(
Status );
00690 }
00691
00692
00693
00694
00695
00696
if (GuardPage) {
00697 RegionSize = SysInfo.PageSize;
00698
Status = ZwProtectVirtualMemory( Process,
00699 (PVOID *)&Stack,
00700 &RegionSize,
00701 PAGE_GUARD | PAGE_READWRITE,
00702 &OldProtect);
00703
00704
00705
if ( !
NT_SUCCESS(
Status ) ) {
00706
#if DBG
00707
DbgPrint(
"NTRTL: RtlpCreateStack( %lx ) failed. Guard Page Creation Status == %X\n",
00708 Process,
00709
Status
00710 );
00711
#endif // DBG
00712
return(
Status );
00713 }
00714
#if defined(_IA64_)
00715
InitialTeb->StackLimit = (PVOID)((PUCHAR)
InitialTeb->StackLimit + RegionSize);
00716
#else
00717
InitialTeb->StackLimit = (PVOID)((PUCHAR)
InitialTeb->StackLimit - RegionSize);
00718
#endif // defined(_IA64_)
00719
}
00720
00721
#if defined(_IA64_)
00722
00723
00724
00725
00726
00727 Bstore =
InitialTeb->StackBase;
00728
if (MaximumBstoreSize > CommittedBstoreSize) {
00729 CommittedBstoreSize += SysInfo.PageSize;
00730 GuardPage =
TRUE;
00731 }
else {
00732 GuardPage =
FALSE;
00733 }
00734
00735
Status = ZwAllocateVirtualMemory( Process,
00736 (PVOID *)&Bstore,
00737 0,
00738 &CommittedBstoreSize,
00739 MEM_COMMIT,
00740 PAGE_READWRITE
00741 );
00742
00743
InitialTeb->BStoreLimit = Bstore + CommittedBstoreSize;
00744
00745
if ( !
NT_SUCCESS(
Status) ) {
00746
#if DBG
00747
DbgPrint(
"NTRTL: RtlpCreateStack( %lx ) failed. Backing Store Commit Status == %X\n",
00748 Process,
00749
Status
00750 );
00751
#endif // DBG
00752
return (
Status);
00753 }
00754
00755
if (GuardPage) {
00756 Bstore = (PCH)
InitialTeb->BStoreLimit - SysInfo.PageSize;
00757 RegionSize = SysInfo.PageSize;
00758
Status = ZwProtectVirtualMemory(Process,
00759 (PVOID *)&Bstore,
00760 &RegionSize,
00761 PAGE_GUARD | PAGE_READWRITE,
00762 &OldProtect
00763 );
00764
if ( !
NT_SUCCESS(
Status) ) {
00765
#if DBG
00766
DbgPrint(
"NTRTL: RtlpCreateStack( %lx ) failed. Backing Store Guard Page Creation Status == %X\n",
00767 Process,
00768
Status
00769 );
00770
#endif // DBG
00771
return (
Status);
00772 }
00773
InitialTeb->BStoreLimit = (PVOID)((PUCHAR)
InitialTeb->BStoreLimit - RegionSize);
00774 }
00775
00776
#endif // defined(_IA64_)
00777
00778
return( STATUS_SUCCESS );
00779 }
00780
00781
00782
NTSTATUS
00783 RtlpFreeStack(
00784 IN HANDLE Process,
00785 IN PINITIAL_TEB InitialTeb
00786 )
00787 {
00788
NTSTATUS Status;
00789 SIZE_T
Zero;
00790
00791
Zero = 0;
00792
Status = ZwFreeVirtualMemory( Process,
00793 &
InitialTeb->StackAllocationBase,
00794 &
Zero,
00795 MEM_RELEASE
00796 );
00797
if ( !
NT_SUCCESS(
Status ) ) {
00798
#if DBG
00799
DbgPrint(
"NTRTL: RtlpFreeStack( %lx ) failed. Stack DeCommit Status == %X\n",
00800 Process,
00801
Status
00802 );
00803
#endif // DBG
00804
return(
Status );
00805 }
00806
00807 RtlZeroMemory(
InitialTeb,
sizeof( *
InitialTeb ) );
00808
return( STATUS_SUCCESS );
00809 }
00810
00811
00812
NTSTATUS
00813 RtlCreateUserProcess(
00814 IN PUNICODE_STRING NtImagePathName,
00815 IN ULONG Attributes,
00816 IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
00817 IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL,
00818 IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
00819 IN HANDLE ParentProcess OPTIONAL,
00820 IN BOOLEAN InheritHandles,
00821 IN HANDLE DebugPort OPTIONAL,
00822 IN HANDLE ExceptionPort OPTIONAL,
00823 OUT PRTL_USER_PROCESS_INFORMATION ProcessInformation
00824 )
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881 {
00882
NTSTATUS Status;
00883 HANDLE Section,
File;
00884 OBJECT_ATTRIBUTES
ObjectAttributes;
00885 PRTL_USER_PROCESS_PARAMETERS Parameters;
00886 SIZE_T ParameterLength;
00887 PVOID Environment;
00888 PWCHAR s;
00889 ULONG EnvironmentLength;
00890 SIZE_T RegionSize;
00891 PROCESS_BASIC_INFORMATION ProcessInfo;
00892 PPEB Peb;
00893 UNICODE_STRING
Unicode;
00894
00895
00896
00897
00898
00899 RtlZeroMemory( ProcessInformation,
sizeof( *ProcessInformation ) );
00900 ProcessInformation->Length =
sizeof( *ProcessInformation );
00901
00902
00903
00904
00905
00906
Status =
RtlpOpenImageFile( NtImagePathName,
00907 Attributes & (OBJ_INHERIT | OBJ_CASE_INSENSITIVE),
00908 &
File,
00909
TRUE
00910 );
00911
if (!
NT_SUCCESS(
Status )) {
00912
return(
Status );
00913 }
00914
00915
00916
00917
00918
00919
00920
Status = ZwCreateSection( &Section,
00921 SECTION_ALL_ACCESS,
00922
NULL,
00923
NULL,
00924 PAGE_EXECUTE,
00925 SEC_IMAGE,
00926
File
00927 );
00928 ZwClose(
File );
00929
if ( !
NT_SUCCESS(
Status ) ) {
00930
return(
Status );
00931 }
00932
00933
00934
00935
00936
00937
00938
00939
00940
if (!ARGUMENT_PRESENT( ParentProcess )) {
00941 ParentProcess = NtCurrentProcess();
00942 }
00943
00944 InitializeObjectAttributes( &
ObjectAttributes,
NULL, 0,
NULL,
00945 ProcessSecurityDescriptor );
00946
if (
RtlGetNtGlobalFlags() & FLG_ENABLE_CSRDEBUG ) {
00947
if ( wcsstr(NtImagePathName->Buffer,
L"csrss") ||
00948 wcsstr(NtImagePathName->Buffer,
L"CSRSS")
00949 ) {
00950
00951
00952
00953
00954
00955
if (
ISTERMINALSERVER()) {
00956
00957 InitializeObjectAttributes( &
ObjectAttributes,
NULL, 0,
NULL,
00958 ProcessSecurityDescriptor );
00959 }
else {
00960
00961
RtlInitUnicodeString(&
Unicode,
L"\\WindowsSS");
00962 InitializeObjectAttributes( &
ObjectAttributes, &
Unicode, 0,
NULL,
00963 ProcessSecurityDescriptor );
00964 }
00965
00966 }
00967 }
00968
00969
if ( !InheritHandles ) {
00970 ProcessParameters->CurrentDirectory.Handle =
NULL;
00971 }
00972
Status = ZwCreateProcess( &ProcessInformation->Process,
00973 PROCESS_ALL_ACCESS,
00974 &
ObjectAttributes,
00975 ParentProcess,
00976 InheritHandles,
00977 Section,
00978
DebugPort,
00979 ExceptionPort
00980 );
00981
if ( !
NT_SUCCESS(
Status ) ) {
00982 ZwClose( Section );
00983
return(
Status );
00984 }
00985
00986
00987
00988
00989
00990
00991
Status = ZwQuerySection( Section,
00992 SectionImageInformation,
00993 &ProcessInformation->ImageInformation,
00994
sizeof( ProcessInformation->ImageInformation ),
00995
NULL
00996 );
00997
if ( !
NT_SUCCESS(
Status ) ) {
00998 ZwClose( ProcessInformation->Process );
00999 ZwClose( Section );
01000
return(
Status );
01001 }
01002
01003
Status = ZwQueryInformationProcess( ProcessInformation->Process,
01004 ProcessBasicInformation,
01005 &ProcessInfo,
01006
sizeof( ProcessInfo ),
01007
NULL
01008 );
01009
if ( !
NT_SUCCESS(
Status ) ) {
01010 ZwClose( ProcessInformation->Process );
01011 ZwClose( Section );
01012
return(
Status );
01013 }
01014
01015 Peb = ProcessInfo.PebBaseAddress;
01016
01017
01018
01019
01020
01021
01022
try {
01023
Status = STATUS_SUCCESS;
01024
01025
if ( ProcessParameters->StandardInput ) {
01026
01027
Status = ZwDuplicateObject(
01028 ParentProcess,
01029 ProcessParameters->StandardInput,
01030 ProcessInformation->Process,
01031 &ProcessParameters->StandardInput,
01032 0
L,
01033 0
L,
01034 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES
01035 );
01036
if ( !
NT_SUCCESS(
Status) ) {
01037
return Status;
01038 }
01039 }
01040
01041
if ( ProcessParameters->StandardOutput ) {
01042
01043
Status = ZwDuplicateObject(
01044 ParentProcess,
01045 ProcessParameters->StandardOutput,
01046 ProcessInformation->Process,
01047 &ProcessParameters->StandardOutput,
01048 0
L,
01049 0
L,
01050 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES
01051 );
01052
if ( !
NT_SUCCESS(
Status) ) {
01053
return Status;
01054 }
01055 }
01056
01057
if ( ProcessParameters->StandardError ) {
01058
01059
Status = ZwDuplicateObject(
01060 ParentProcess,
01061 ProcessParameters->StandardError,
01062 ProcessInformation->Process,
01063 &ProcessParameters->StandardError,
01064 0
L,
01065 0
L,
01066 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES
01067 );
01068
if ( !
NT_SUCCESS(
Status) ) {
01069
return Status;
01070 }
01071 }
01072
01073 } finally {
01074
if ( !
NT_SUCCESS(
Status) ) {
01075 ZwClose( ProcessInformation->Process );
01076 ZwClose( Section );
01077 }
01078 }
01079
01080
01081
01082
01083
01084
if (ProcessInformation->ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_NATIVE ) {
01085
if ( ProcessParameters->Flags & RTL_USER_PROC_RESERVE_1MB ) {
01086
01087
#if defined(_IA64_)
01088
Environment = (PVOID)(UADDRESS_BASE+4);
01089
#else
01090
Environment = (PVOID)(4);
01091
#endif
01092
RegionSize = (1024*1024)-(256);
01093
01094
Status = ZwAllocateVirtualMemory( ProcessInformation->Process,
01095 (PVOID *)&Environment,
01096 0,
01097 &RegionSize,
01098 MEM_RESERVE,
01099 PAGE_READWRITE
01100 );
01101
if ( !
NT_SUCCESS(
Status ) ) {
01102 ZwClose( ProcessInformation->Process );
01103 ZwClose( Section );
01104
return(
Status );
01105 }
01106 }
01107 }
01108
01109
01110
01111
01112
01113
01114
01115
01116
if (s = (PWCHAR)ProcessParameters->Environment) {
01117
while (*s++) {
01118
while (*s++) {
01119 }
01120 }
01121 EnvironmentLength = (ULONG)(s - (PWCHAR)ProcessParameters->Environment) *
sizeof(WCHAR);
01122
01123 Environment =
NULL;
01124 RegionSize = EnvironmentLength;
01125
Status = ZwAllocateVirtualMemory( ProcessInformation->Process,
01126 (PVOID *)&Environment,
01127 0,
01128 &RegionSize,
01129 MEM_COMMIT,
01130 PAGE_READWRITE
01131 );
01132
if ( !
NT_SUCCESS(
Status ) ) {
01133 ZwClose( ProcessInformation->Process );
01134 ZwClose( Section );
01135
return(
Status );
01136 }
01137
01138
Status = ZwWriteVirtualMemory( ProcessInformation->Process,
01139 Environment,
01140 ProcessParameters->Environment,
01141 EnvironmentLength,
01142
NULL
01143 );
01144
if ( !
NT_SUCCESS(
Status ) ) {
01145 ZwClose( ProcessInformation->Process );
01146 ZwClose( Section );
01147
return(
Status );
01148 }
01149
01150 ProcessParameters->Environment = Environment;
01151 }
01152
01153
01154
01155
01156
01157
01158
01159
01160 Parameters =
NULL;
01161 ParameterLength = ProcessParameters->MaximumLength;
01162
Status = ZwAllocateVirtualMemory( ProcessInformation->Process,
01163 (PVOID *)&Parameters,
01164 0,
01165 &ParameterLength,
01166 MEM_COMMIT,
01167 PAGE_READWRITE
01168 );
01169
if ( !
NT_SUCCESS(
Status ) ) {
01170 ZwClose( ProcessInformation->Process );
01171 ZwClose( Section );
01172
return(
Status );
01173 }
01174
01175
Status = ZwWriteVirtualMemory( ProcessInformation->Process,
01176 Parameters,
01177 ProcessParameters,
01178 ProcessParameters->Length,
01179
NULL
01180 );
01181
if ( !
NT_SUCCESS(
Status ) ) {
01182 ZwClose( ProcessInformation->Process );
01183 ZwClose( Section );
01184
return(
Status );
01185 }
01186
01187
Status = ZwWriteVirtualMemory( ProcessInformation->Process,
01188 &Peb->ProcessParameters,
01189 &Parameters,
01190
sizeof( Parameters ),
01191
NULL
01192 );
01193
if ( !
NT_SUCCESS(
Status ) ) {
01194 ZwClose( ProcessInformation->Process );
01195 ZwClose( Section );
01196
return(
Status );
01197 }
01198
01199
01200
01201
01202
01203
01204
01205
01206
Status =
RtlCreateUserThread(
01207 ProcessInformation->Process,
01208 ThreadSecurityDescriptor,
01209
TRUE,
01210 ProcessInformation->ImageInformation.ZeroBits,
01211 ProcessInformation->ImageInformation.MaximumStackSize,
01212 ProcessInformation->ImageInformation.CommittedStackSize,
01213 (PUSER_THREAD_START_ROUTINE)
01214 ProcessInformation->ImageInformation.TransferAddress,
01215 (PVOID)Peb,
01216 &ProcessInformation->Thread,
01217 &ProcessInformation->ClientId
01218 );
01219
if ( !
NT_SUCCESS(
Status ) ) {
01220 ZwClose( ProcessInformation->Process );
01221 ZwClose( Section );
01222
return(
Status );
01223 }
01224
01225
01226
01227
01228
01229
01230 ZwClose( Section );
01231
01232
01233
01234
01235
01236
return( STATUS_SUCCESS );
01237 }
01238
01239
01240
NTSTATUS
01241 RtlCreateUserThread(
01242 IN HANDLE Process,
01243 IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
01244 IN BOOLEAN CreateSuspended,
01245 IN ULONG ZeroBits OPTIONAL,
01246 IN SIZE_T MaximumStackSize OPTIONAL,
01247 IN SIZE_T CommittedStackSize OPTIONAL,
01248 IN PUSER_THREAD_START_ROUTINE StartAddress,
01249 IN PVOID Parameter OPTIONAL,
01250 OUT PHANDLE Thread OPTIONAL,
01251 OUT PCLIENT_ID ClientId OPTIONAL
01252 )
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306 {
01307
NTSTATUS Status;
01308 CONTEXT
ThreadContext;
01309 OBJECT_ATTRIBUTES
ObjectAttributes;
01310 INITIAL_TEB
InitialTeb;
01311 HANDLE
ThreadHandle;
01312 CLIENT_ID
ThreadClientId;
01313
01314
01315
01316
01317
01318
01319
Status =
RtlpCreateStack( Process,
01320 MaximumStackSize,
01321 CommittedStackSize,
01322 ZeroBits,
01323 &
InitialTeb
01324 );
01325
if ( !
NT_SUCCESS(
Status ) ) {
01326
return(
Status );
01327 }
01328
01329
01330
01331
01332
01333
01334
RtlInitializeContext( Process,
01335 &
ThreadContext,
01336 Parameter,
01337 (PVOID)StartAddress,
01338
InitialTeb.StackBase
01339 );
01340
01341
01342
01343
01344
01345
01346
01347 InitializeObjectAttributes( &
ObjectAttributes,
NULL, 0,
NULL,
01348 ThreadSecurityDescriptor );
01349
Status = ZwCreateThread( &
ThreadHandle,
01350 THREAD_ALL_ACCESS,
01351 &
ObjectAttributes,
01352 Process,
01353 &
ThreadClientId,
01354 &
ThreadContext,
01355 &
InitialTeb,
01356 CreateSuspended
01357 );
01358
if (!
NT_SUCCESS(
Status )) {
01359
#if DBG
01360
DbgPrint(
"NTRTL: RtlCreateUserThread Failed. NtCreateThread Status == %X\n",
01361
Status );
01362
#endif // DBG
01363
RtlpFreeStack( Process, &
InitialTeb );
01364 }
01365
else {
01366
if (ARGUMENT_PRESENT( Thread )) {
01367 *Thread =
ThreadHandle;
01368 }
01369
01370
if (ARGUMENT_PRESENT( ClientId )) {
01371 *ClientId =
ThreadClientId;
01372 }
01373
01374 }
01375
01376
01377
01378
01379
01380
return(
Status );
01381 }
01382
01383
01384
VOID
01385 RtlFreeUserThreadStack(
01386 HANDLE hProcess,
01387 HANDLE hThread
01388 )
01389 {
01390
NTSTATUS Status;
01391 PTEB Teb;
01392 THREAD_BASIC_INFORMATION ThreadInfo;
01393 PVOID StackDeallocationBase;
01394 ULONG Length;
01395 SIZE_T
Size;
01396
01397
Status =
NtQueryInformationThread( hThread,
01398 ThreadBasicInformation,
01399 &ThreadInfo,
01400
sizeof( ThreadInfo ),
01401
NULL
01402 );
01403 Teb = ThreadInfo.TebBaseAddress;
01404
if (!
NT_SUCCESS(
Status ) || !Teb) {
01405
return;
01406 }
01407
01408
Status =
NtReadVirtualMemory( hProcess,
01409 &Teb->DeallocationStack,
01410 &StackDeallocationBase,
01411
sizeof( StackDeallocationBase ),
01412 &Length
01413 );
01414
if (!
NT_SUCCESS(
Status ) || !StackDeallocationBase) {
01415
return;
01416 }
01417
01418
Size = 0;
01419
NtFreeVirtualMemory( hProcess, &StackDeallocationBase, &
Size, MEM_RELEASE );
01420
return;
01421 }