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
00027
#include "iop.h"
00028
#pragma hdrstop
00029
00030
#include <ntddip.h>
00031
#include <nbtioctl.h>
00032
#include <ntddnfs.h>
00033
#include <ntddbrow.h>
00034
#include <ntddtcp.h>
00035
#include <setupblk.h>
00036
#include <remboot.h>
00037
#include <oscpkt.h>
00038
#include <windef.h>
00039
#include <tdiinfo.h>
00040
#if defined(REMOTE_BOOT)
00041
#include <ntddndis.h>
00042
#include <ipsec.h>
00043
#endif // defined(REMOTE_BOOT)
00044
00045
#ifndef NT
00046
#define NT
00047
#include <ipinfo.h>
00048
#undef NT
00049
#else
00050
#include <ipinfo.h>
00051
#endif
00052
00053 extern BOOLEAN
ExpInTextModeSetup;
00054
00055
00056
00057
00058
00059 #define DEFAULT_DEST 0
00060 #define DEFAULT_DEST_MASK 0
00061 #define DEFAULT_METRIC 1
00062
00063
NTSTATUS
00064
IopWriteIpAddressToRegistry(
00065 HANDLE handle,
00066 PWCHAR regkey,
00067 PUCHAR value
00068 );
00069
00070
NTSTATUS
00071
IopTCPQueryInformationEx(
00072 IN HANDLE TCPHandle,
00073 IN TDIObjectID FAR *ID,
00074 OUT
void FAR *Buffer,
00075 IN OUT DWORD FAR *BufferSize,
00076 IN OUT BYTE FAR *Context
00077 );
00078
00079
NTSTATUS
00080
IopTCPSetInformationEx(
00081 IN HANDLE TCPHandle,
00082 IN TDIObjectID FAR *ID,
00083 IN
void FAR *Buffer,
00084 IN DWORD FAR BufferSize
00085 );
00086
00087
NTSTATUS
00088
IopSetDefaultGateway(
00089 IN ULONG GatewayAddress
00090 );
00091
00092
NTSTATUS
00093
IopCacheNetbiosNameForIpAddress(
00094 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00095 );
00096
00097
VOID
00098
IopAssignNetworkDriveLetter (
00099 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00100 );
00101
00102
#if defined(REMOTE_BOOT)
00103
00104
#if DBG
00105
BOOLEAN DebugReset =
FALSE;
00106
#endif
00107
00108
00109
00110
00111
00112 BOOLEAN TextmodeSetupHasStartedCsc =
FALSE;
00113
00114
00115
00116
00117
00118
typedef struct _FILETIME {
00119 ULONG dwLowDateTime;
00120 ULONG dwHighDateTime;
00121 } FILETIME, *LPFILETIME;
00122
00123
typedef struct _WIN32_FIND_DATAA {
00124 ULONG dwFileAttributes;
00125 FILETIME ftCreationTime;
00126 FILETIME ftLastAccessTime;
00127 FILETIME ftLastWriteTime;
00128 ULONG nFileSizeHigh;
00129 ULONG nFileSizeLow;
00130 ULONG dwReserved0;
00131 ULONG dwReserved1;
00132
CHAR cFileName[
MAX_PATH ];
00133
CHAR cAlternateFileName[ 14 ];
00134 } WIN32_FIND_DATAA;
00135
00136
typedef struct _WIN32_FIND_DATAW {
00137
DWORD dwFileAttributes;
00138 FILETIME ftCreationTime;
00139 FILETIME ftLastAccessTime;
00140 FILETIME ftLastWriteTime;
00141
DWORD nFileSizeHigh;
00142
DWORD nFileSizeLow;
00143
DWORD dwReserved0;
00144
DWORD dwReserved1;
00145 WCHAR cFileName[
MAX_PATH ];
00146 WCHAR cAlternateFileName[ 14 ];
00147 } WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW;
00148
00149
00150 LIST_ENTRY DirectoryList;
00151
00152 HANDLE RdrHandle =
NULL;
00153
PKPROCESS RdrHandleProcess =
NULL;
00154
00155
typedef enum _START_CSC {
00156 INIT_CSC,
00157 FLUSH_CSC
00158 } START_CSC;
00159
00160 START_CSC StartCsc;
00161
00162
typedef enum _CSC_CONTROL {
00163 READ_CSC,
00164 SET_FLUSH_CSC,
00165 SET_FLUSHED_CSC
00166 } CSC_CONTROL;
00167
00168
#include <shdcom.h>
00169
00170
00171
00172
00173
00174
typedef struct _DIRENT {
00175 LIST_ENTRY Next;
00176 UNICODE_STRING
Directory;
00177 PWCHAR LastToken;
00178 HSHADOW CSCHandle;
00179 WCHAR
Name[1];
00180 } DIRENT, *PDIRENT;
00181
00182
NTSTATUS
00183 IopInitCsc(
00184 IN PUCHAR CscPath
00185 );
00186
00187
NTSTATUS
00188 IopResetCsc(
00189 IN PUCHAR CscPath
00190 );
00191
00192 PWSTR
00193 IopBreakPath(
00194 IN PWSTR* Path
00195 );
00196
00197
NTSTATUS
00198 IopMarkRoot(
00199 IN PUNICODE_STRING FileName,
00200 OUT PHSHADOW RootHandle
00201 );
00202
00203
VOID
00204 IopSetFlushCSC(
00205 IN CSC_CONTROL Command
00206 );
00207
00208
NTSTATUS
00209 IopWalkDirectoryHelper (
00210 IN PUNICODE_STRING Directory,
00211 IN HSHADOW CSCHandle,
00212 IN PUCHAR Buffer,
00213 IN ULONG BufferSize
00214 );
00215
00216
NTSTATUS
00217 IopWalkDirectoryTree (
00218 IN PUNICODE_STRING Directory,
00219 IN HSHADOW CSCHandle
00220 );
00221
00222
NTSTATUS
00223 IopGetShadowExW(
00224 HSHADOW hDir,
00225 LPWIN32_FIND_DATAW lpFind32,
00226 LPSHADOWINFO lpSI
00227 );
00228
00229
NTSTATUS
00230 IopAddHintFromInode(
00231 HSHADOW hDir,
00232 HSHADOW hShadow,
00233 ULONG *lpulHintPri,
00234 ULONG *lpulHintFlags,
00235 ULONG HintFlagsToSet
00236 );
00237
00238
NTSTATUS
00239 IopSetShadowInfoW(
00240 HSHADOW hDir,
00241 HSHADOW hShadow,
00242 ULONG uStatus,
00243 ULONG uOp
00244 );
00245
00246
NTSTATUS
00247 IopCreateShadowW(
00248 HSHADOW hDir,
00249 LPWIN32_FIND_DATAW lpFind32,
00250 ULONG uStatus,
00251 PHSHADOW lphShadow
00252 );
00253
00254
NTSTATUS
00255 IopCopyServerAcl(
00256 HANDLE ParentHandle,
00257 PWCHAR FileName,
00258 HSHADOW ShadowHandle,
00259 BOOLEAN IsDirectory,
00260 PUCHAR Buffer,
00261 ULONG BufferSize
00262 );
00263
00264
NTSTATUS
00265 IopGetShadowPathW(
00266 HSHADOW hShadow,
00267 PWCHAR lpLocalPath,
00268 LPCOPYPARAMSW lpCP
00269 );
00270
00271
VOID
00272 IopEnableRemoteBootSecurity (
00273 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00274 );
00275
00276
VOID
00277 IopGetHarddiskInfo(
00278 OUT PWSTR NetHDCSCPartition
00279 );
00280
00281
#endif // defined(REMOTE_BOOT)
00282
00283
00284
00285
00286
00287
00288
#ifdef ALLOC_PRAGMA
00289
#pragma alloc_text(INIT,IopAddRemoteBootValuesToRegistry)
00290
#pragma alloc_text(INIT,IopStartNetworkForRemoteBoot)
00291
#pragma alloc_text(INIT,IopStartTcpIpForRemoteBoot)
00292
#pragma alloc_text(INIT,IopIsRemoteBootCard)
00293
#pragma alloc_text(INIT,IopSetupRemoteBootCard)
00294
#if defined(REMOTE_BOOT)
00295
#pragma alloc_text(INIT,IopAssignNetworkDriveLetter)
00296
#pragma alloc_text(INIT,IopInitCsc)
00297
#pragma alloc_text(INIT,IopResetCsc)
00298
#pragma alloc_text(INIT,IopBreakPath)
00299
#pragma alloc_text(INIT,IopMarkRoot)
00300
#pragma alloc_text(INIT,IopSetFlushCSC)
00301
#pragma alloc_text(INIT,IopWalkDirectoryHelper)
00302
#pragma alloc_text(INIT,IopWalkDirectoryTree)
00303
#pragma alloc_text(INIT,IopGetShadowExW)
00304
#pragma alloc_text(INIT,IopAddHintFromInode)
00305
#pragma alloc_text(INIT,IopCreateShadowW)
00306
#pragma alloc_text(INIT,IopCopyServerAcl)
00307
#pragma alloc_text(INIT,IopGetShadowPathW)
00308
#pragma alloc_text(INIT,IopGetHarddiskInfo)
00309
#endif // defined(REMOTE_BOOT)
00310
#endif
00311
00312
00313
NTSTATUS
00314 IopAddRemoteBootValuesToRegistry (
00315
PLOADER_PARAMETER_BLOCK LoaderBlock
00316 )
00317 {
00318
NTSTATUS status = STATUS_SUCCESS;
00319 HANDLE handle;
00320 HANDLE serviceHandle;
00321 OBJECT_ATTRIBUTES objectAttributes;
00322 UNICODE_STRING string;
00323
CHAR addressA[16];
00324 WCHAR addressW[16];
00325 STRING addressStringA;
00326 UNICODE_STRING addressStringW;
00327 PUCHAR addressPointer;
00328 PUCHAR p;
00329 PUCHAR q;
00330 UCHAR ntName[128];
00331 WCHAR imagePath[128];
00332 STRING ansiString;
00333 UNICODE_STRING unicodeString;
00334 UNICODE_STRING dnsNameString;
00335 UNICODE_STRING netbiosNameString;
00336 ULONG tmpValue;
00337
00338
if (LoaderBlock->
SetupLoaderBlock->
ComputerName[0] != 0) {
00339
00340
00341
00342
00343
00344 _wcsupr( LoaderBlock->
SetupLoaderBlock->
ComputerName );
00345
00346
RtlInitUnicodeString( &dnsNameString, LoaderBlock->
SetupLoaderBlock->
ComputerName );
00347
00348 status =
RtlDnsHostNameToComputerName(
00349 &netbiosNameString,
00350 &dnsNameString,
00351
TRUE);
00352
00353
if ( !
NT_SUCCESS(status) ) {
00354 KdPrint((
"IopAddRemoteBootValuesToRegistry: Failed RtlDnsHostNameToComputerName: %x\n", status ));
00355
goto cleanup;
00356 }
00357
00358
00359
00360
00361
00362
RtlInitUnicodeString( &string,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ComputerName" );
00363
00364 InitializeObjectAttributes(
00365 &objectAttributes,
00366 &string,
00367 OBJ_CASE_INSENSITIVE,
00368
NULL,
00369
NULL
00370 );
00371
00372 status =
NtOpenKey( &handle, KEY_ALL_ACCESS, &objectAttributes );
00373
if ( !
NT_SUCCESS(status) ) {
00374 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to open ComputerName key: %x\n", status ));
00375
RtlFreeUnicodeString( &netbiosNameString );
00376
goto cleanup;
00377 }
00378
00379
RtlInitUnicodeString( &string,
L"ComputerName" );
00380
00381 status =
NtSetValueKey(
00382 handle,
00383 &string,
00384 0,
00385 REG_SZ,
00386 netbiosNameString.Buffer,
00387 netbiosNameString.Length +
sizeof(WCHAR)
00388 );
00389
NtClose( handle );
00390
RtlFreeUnicodeString( &netbiosNameString );
00391
00392
if ( !
NT_SUCCESS(status) ) {
00393 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to set ComputerName value: %x\n", status ));
00394
goto cleanup;
00395 }
00396
00397
00398
00399
00400
00401
RtlInitUnicodeString( &string,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters" );
00402
00403 InitializeObjectAttributes(
00404 &objectAttributes,
00405 &string,
00406 OBJ_CASE_INSENSITIVE,
00407
NULL,
00408
NULL
00409 );
00410
00411 status =
NtOpenKey( &handle, KEY_ALL_ACCESS, &objectAttributes );
00412
if ( !
NT_SUCCESS(status) ) {
00413 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to open Tcpip\\Parameters key: %x\n", status ));
00414
goto cleanup;
00415 }
00416
00417 _wcslwr( LoaderBlock->
SetupLoaderBlock->
ComputerName );
00418
00419
RtlInitUnicodeString( &string,
L"Hostname" );
00420
00421 status =
NtSetValueKey(
00422 handle,
00423 &string,
00424 0,
00425 REG_SZ,
00426 LoaderBlock->
SetupLoaderBlock->
ComputerName,
00427 (wcslen(LoaderBlock->
SetupLoaderBlock->
ComputerName) + 1) *
sizeof(WCHAR)
00428 );
00429
NtClose( handle );
00430
if ( !
NT_SUCCESS(status) ) {
00431 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to set Hostname value: %x\n", status ));
00432
goto cleanup;
00433 }
00434 }
00435
00436
00437
00438
00439
00440
ASSERT( _stricmp(LoaderBlock->
ArcBootDeviceName,
"net(0)") == 0 );
00441
00442
RtlInitUnicodeString( &string,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control" );
00443
00444 InitializeObjectAttributes(
00445 &objectAttributes,
00446 &string,
00447 OBJ_CASE_INSENSITIVE,
00448
NULL,
00449
NULL
00450 );
00451
00452 status =
NtOpenKey( &handle, KEY_ALL_ACCESS, &objectAttributes );
00453
if ( !
NT_SUCCESS(status) ) {
00454 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to open Control key: %x\n", status ));
00455
goto skiproot;
00456 }
00457
00458 p = strrchr( LoaderBlock->
NtBootPathName,
'\\' );
00459
if ( (p !=
NULL) && (*(p+1) == 0) ) {
00460
00461
00462
00463
00464
00465
00466 q = p;
00467 *q = 0;
00468 p = strrchr( LoaderBlock->
NtBootPathName,
'\\' );
00469 *q =
'\\';
00470 }
00471
if ( p ==
NULL ) {
00472 KdPrint((
"IopAddRemoteBootValuesToRegistry: malformed NtBootPathName: %s\n", LoaderBlock->
NtBootPathName ));
00473
NtClose( handle );
00474
goto skiproot;
00475 }
00476 *p = 0;
00477
00478
#if defined(REMOTE_BOOT)
00479
00480
00481
00482
00483
00484 SharedUserData->RemoteBootServerPath[0] =
L'\\';
00485
RtlInitAnsiString( &ansiString, LoaderBlock->
NtBootPathName );
00486 unicodeString.MaximumLength =
sizeof(SharedUserData->RemoteBootServerPath) - (2 *
sizeof(WCHAR));
00487 unicodeString.Buffer = &SharedUserData->RemoteBootServerPath[1];
00488
RtlAnsiStringToUnicodeString( &unicodeString, &ansiString,
FALSE );
00489 SharedUserData->RemoteBootServerPath[1 + (unicodeString.Length/
sizeof(WCHAR))] = 0;
00490
#endif // defined(REMOTE_BOOT)
00491
00492 strcpy( ntName,
"\\Device\\LanmanRedirector");
00493 strcat( ntName, LoaderBlock->
NtBootPathName );
00494 *p =
'\\';
00495
00496
RtlInitAnsiString( &ansiString, ntName );
00497
RtlAnsiStringToUnicodeString( &unicodeString, &ansiString,
TRUE );
00498
00499
RtlInitUnicodeString( &string,
L"RemoteBootRoot" );
00500
00501 status =
NtSetValueKey(
00502 handle,
00503 &string,
00504 0,
00505 REG_SZ,
00506 unicodeString.Buffer,
00507 unicodeString.Length +
sizeof(WCHAR)
00508 );
00509
00510
RtlFreeUnicodeString( &unicodeString );
00511
if ( !
NT_SUCCESS(status) ) {
00512 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to set RemoteBootRoot value: %x\n", status ));
00513 }
00514
00515
if ((LoaderBlock->
SetupLoaderBlock->
Flags &
SETUPBLK_FLAGS_IS_TEXTMODE) != 0) {
00516
00517 strcpy( ntName,
"\\Device\\LanmanRedirector");
00518 strcat( ntName, LoaderBlock->
SetupLoaderBlock->
MachineDirectoryPath );
00519
RtlInitAnsiString( &ansiString, ntName );
00520
RtlAnsiStringToUnicodeString( &unicodeString, &ansiString,
TRUE );
00521
00522
RtlInitUnicodeString( &string,
L"RemoteBootMachineDirectory" );
00523
00524 status =
NtSetValueKey(
00525 handle,
00526 &string,
00527 0,
00528 REG_SZ,
00529 unicodeString.Buffer,
00530 unicodeString.Length +
sizeof(WCHAR)
00531 );
00532
00533
RtlFreeUnicodeString( &unicodeString );
00534
if ( !
NT_SUCCESS(status) ) {
00535 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to set RemoteBootMachineDirectory value: %x\n", status ));
00536 }
00537 }
00538
00539
NtClose( handle );
00540
00541 skiproot:
00542
00543
#if defined(REMOTE_BOOT)
00544
StartCsc = INIT_CSC;
00545 IopSetFlushCSC(READ_CSC);
00546
00547
if ( (StartCsc != FLUSH_CSC) &&
00548 ((LoaderBlock->
SetupLoaderBlock->
Flags & SETUPBLK_FLAGS_REPIN) != 0) ) {
00549 StartCsc = FLUSH_CSC;
00550 IopSetFlushCSC(SET_FLUSH_CSC);
00551 }
00552
00553
#if 0
00554
RtlInitUnicodeString( &string,
L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CSCSettings" );
00555
00556 InitializeObjectAttributes(
00557 &objectAttributes,
00558 &string,
00559 OBJ_CASE_INSENSITIVE,
00560
NULL,
00561
NULL
00562 );
00563
00564 status =
NtOpenKey( &handle, KEY_ALL_ACCESS, &objectAttributes );
00565
00566
if (
NT_SUCCESS(status) ) {
00567
00568 PKEY_VALUE_PARTIAL_INFORMATION keyValue;
00569 UCHAR buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
sizeof(
DWORD)];
00570 ULONG length;
00571
DWORD disabled;
00572
00573
#define ONE_BOOT 2
00574
00575
RtlInitUnicodeString( &string,
L"DisableAgent" );
00576
00577
if ( (LoaderBlock->
SetupLoaderBlock->
Flags & SETUPBLK_FLAGS_DISABLE_CSC) == 0 ) {
00578
00579
00580
00581
00582
00583 disabled = ONE_BOOT;
00584 status =
NtSetValueKey(
00585 handle,
00586 &string,
00587 0,
00588 REG_DWORD,
00589 &disabled,
00590
sizeof(
DWORD));
00591
00592 }
else {
00593
00594 keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
00595 status =
NtQueryValueKey(
00596 handle,
00597 &string,
00598 KeyValuePartialInformation,
00599 keyValue,
00600
sizeof(buffer),
00601 &length);
00602
if (
NT_SUCCESS(status)) {
00603 disabled = *((
DWORD *)(&keyValue->Data[0]));
00604
00605
if (disabled == ONE_BOOT) {
00606
00607 status =
NtDeleteValueKey( handle, &string);
00608
00609 }
00610 }
00611 }
00612
00613
NtClose( handle );
00614
if ( !
NT_SUCCESS(status) ) {
00615 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to set CSCSettings: %x\n", status ));
00616
goto cleanup;
00617 }
00618 }
00619
#endif
00620
#endif // defined(REMOTE_BOOT)
00621
00622
00623
00624
00625
00626
00627
00628
00629
RtlInitUnicodeString( &string,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\{54C7D140-09EF-11D1-B25A-F5FE627ED95E}" );
00630
00631 InitializeObjectAttributes(
00632 &objectAttributes,
00633 &string,
00634 OBJ_CASE_INSENSITIVE,
00635
NULL,
00636
NULL
00637 );
00638
00639 status =
NtOpenKey( &handle, KEY_ALL_ACCESS, &objectAttributes );
00640
if ( !
NT_SUCCESS(status) ) {
00641 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to open Tcpip\\Parameters\\Interfaces\\{54C7D140-09EF-11D1-B25A-F5FE627ED95E} key: %x\n", status ));
00642
goto cleanup;
00643 }
00644
00645 status =
IopWriteIpAddressToRegistry(handle,
00646
L"DhcpIPAddress",
00647 (PUCHAR)&(LoaderBlock->
SetupLoaderBlock->
IpAddress)
00648 );
00649
00650
if ( !
NT_SUCCESS(status)) {
00651
NtClose(handle);
00652 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to write DhcpIPAddress: %x\n", status ));
00653
goto cleanup;
00654 }
00655
00656 status =
IopWriteIpAddressToRegistry(handle,
00657
L"DhcpSubnetMask",
00658 (PUCHAR)&(LoaderBlock->
SetupLoaderBlock->
SubnetMask)
00659 );
00660
00661
if ( !
NT_SUCCESS(status)) {
00662
NtClose(handle);
00663 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to write DhcpSubnetMask: %x\n", status ));
00664
goto cleanup;
00665 }
00666
00667 status =
IopWriteIpAddressToRegistry(handle,
00668
L"DhcpDefaultGateway",
00669 (PUCHAR)&(LoaderBlock->
SetupLoaderBlock->
DefaultRouter)
00670 );
00671
00672
NtClose(handle);
00673
00674
if ( !
NT_SUCCESS(status)) {
00675 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to write DhcpDefaultGateway: %x\n", status ));
00676
goto cleanup;
00677 }
00678
00679
00680
00681
00682
00683
00684 status =
IopOpenRegistryKey(&handle,
00685
NULL,
00686 &
CmRegistryMachineSystemCurrentControlSetServices,
00687 KEY_ALL_ACCESS,
00688
FALSE
00689 );
00690
00691
if (!
NT_SUCCESS(status)) {
00692 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to open CurrentControlSet\\Services: %x\n", status ));
00693
goto cleanup;
00694 }
00695
00696
RtlInitUnicodeString(&string, LoaderBlock->
SetupLoaderBlock->
NetbootCardServiceName);
00697
00698 InitializeObjectAttributes(&objectAttributes,
00699 &string,
00700 OBJ_CASE_INSENSITIVE,
00701 handle,
00702 (PSECURITY_DESCRIPTOR)
NULL
00703 );
00704
00705 status = ZwCreateKey(&serviceHandle,
00706 KEY_ALL_ACCESS,
00707 &objectAttributes,
00708 0,
00709 (PUNICODE_STRING)
NULL,
00710 0,
00711 &tmpValue
00712 );
00713
00714 ZwClose(handle);
00715
00716
if (!
NT_SUCCESS(status)) {
00717 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to open/create netboot card service key: %x\n", status ));
00718
goto cleanup;
00719 }
00720
00721
00722
00723
00724
00725 PiWstrToUnicodeString(&string,
L"ImagePath");
00726 wcscpy(imagePath,
L"system32\\drivers\\");
00727 wcscat(imagePath, LoaderBlock->
SetupLoaderBlock->
NetbootCardDriverName);
00728
00729 status = ZwSetValueKey(serviceHandle,
00730 &string,
00731
TITLE_INDEX_VALUE,
00732 REG_SZ,
00733 imagePath,
00734 (wcslen(imagePath) + 1) *
sizeof(WCHAR)
00735 );
00736
00737
if (!
NT_SUCCESS(status)) {
00738
NtClose(serviceHandle);
00739 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to write ImagePath: %x\n", status ));
00740
goto cleanup;
00741 }
00742
00743
00744
00745
00746
00747 PiWstrToUnicodeString(&string,
L"Type");
00748 tmpValue = 1;
00749
00750 ZwSetValueKey(serviceHandle,
00751 &string,
00752
TITLE_INDEX_VALUE,
00753 REG_DWORD,
00754 &tmpValue,
00755
sizeof(tmpValue)
00756 );
00757
00758
NtClose(serviceHandle);
00759
00760
if (!
NT_SUCCESS(status)) {
00761 KdPrint((
"IopAddRemoteBootValuesToRegistry: Unable to write Type: %x\n", status ));
00762 }
00763
00764 cleanup:
00765
00766
return status;
00767 }
00768
00769
NTSTATUS
00770 IopStartNetworkForRemoteBoot (
00771
PLOADER_PARAMETER_BLOCK LoaderBlock
00772 )
00773 {
00774
NTSTATUS status;
00775 HANDLE dgHandle;
00776 HANDLE keyHandle;
00777 OBJECT_ATTRIBUTES objectAttributes;
00778 IO_STATUS_BLOCK ioStatusBlock;
00779 UNICODE_STRING string;
00780 UNICODE_STRING computerName;
00781 UNICODE_STRING domainName;
00782 PUCHAR buffer;
00783 ULONG bufferLength;
00784 PLMR_REQUEST_PACKET rrp;
00785 PLMDR_REQUEST_PACKET drrp;
00786 WKSTA_INFO_502 wkstaConfig;
00787 WKSTA_TRANSPORT_INFO_0 wkstaTransportInfo;
00788 LARGE_INTEGER interval;
00789 ULONG length;
00790 PKEY_VALUE_PARTIAL_INFORMATION keyValue;
00791 BOOLEAN startDatagramReceiver;
00792 ULONG enumerateAttempts;
00793
#if defined(REMOTE_BOOT)
00794
PWSTR NetHDCSCPartition;
00795 BOOLEAN leaveRdrHandleOpen;
00796 BOOLEAN pinNetDriver;
00797
#else
00798
HANDLE RdrHandle;
00799
#endif // defined(REMOTE_BOOT)
00800
00801
00802
00803
00804
00805 buffer =
NULL;
00806 computerName.Buffer =
NULL;
00807 domainName.Buffer =
NULL;
00808 dgHandle =
NULL;
00809 RdrHandle =
NULL;
00810
#if defined(REMOTE_BOOT)
00811
NetHDCSCPartition =
NULL;
00812 leaveRdrHandleOpen =
FALSE;
00813 pinNetDriver =
FALSE;
00814
#endif // defined(REMOTE_BOOT)
00815
00816
00817
00818
00819
00820
00821 bufferLength =
max(
sizeof(LMR_REQUEST_PACKET) + (
MAX_PATH + 1) *
sizeof(WCHAR) +
00822 (DNLEN + 1) *
sizeof(WCHAR),
00823
max(
sizeof(LMDR_REQUEST_PACKET),
00824 FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
MAX_PATH));
00825 bufferLength =
max(bufferLength,
sizeof(LMMR_RI_INITIALIZE_SECRET));
00826
00827
#if defined(REMOTE_BOOT)
00828
NetHDCSCPartition =
ExAllocatePoolWithTag(
00829
NonPagedPool,
00830 (80 *
sizeof(WCHAR)) + bufferLength,
00831 'bRoI'
00832 );
00833
if (NetHDCSCPartition ==
NULL) {
00834 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to allocate buffer\n"));
00835 status = STATUS_INSUFFICIENT_RESOURCES;
00836
goto cleanup;
00837 }
00838 buffer = (PUCHAR)(NetHDCSCPartition + 80);
00839
#else
00840
buffer =
ExAllocatePoolWithTag(
NonPagedPool, bufferLength, 'bRoI' );
00841
if (buffer ==
NULL) {
00842 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to allocate buffer\n"));
00843 status = STATUS_INSUFFICIENT_RESOURCES;
00844
goto cleanup;
00845 }
00846
#endif // defined(REMOTE_BOOT)
00847
00848 rrp = (PLMR_REQUEST_PACKET)buffer;
00849 drrp = (PLMDR_REQUEST_PACKET)buffer;
00850
00851
00852
00853
00854
00855
RtlInitUnicodeString( &string,
L"\\Device\\LanmanRedirector" );
00856
00857 InitializeObjectAttributes(
00858 &objectAttributes,
00859 &string,
00860 OBJ_CASE_INSENSITIVE,
00861
NULL,
00862
NULL
00863 );
00864
00865 status =
NtCreateFile(
00866 &RdrHandle,
00867 GENERIC_READ | GENERIC_WRITE,
00868 &objectAttributes,
00869 &ioStatusBlock,
00870
NULL,
00871 0,
00872 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
00873 FILE_OPEN,
00874 FILE_SYNCHRONOUS_IO_NONALERT,
00875
NULL,
00876 0
00877 );
00878
if ( !
NT_SUCCESS(status) ) {
00879 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to open redirector: %x\n", status ));
00880
goto cleanup;
00881 }
00882
00883
#if defined(REMOTE_BOOT)
00884
RdrHandleProcess = &
IoGetCurrentProcess()->
Pcb;
00885
#endif // defined(REMOTE_BOOT)
00886
00887
RtlInitUnicodeString( &string, DD_BROWSER_DEVICE_NAME_U );
00888
00889 InitializeObjectAttributes(
00890 &objectAttributes,
00891 &string,
00892 OBJ_CASE_INSENSITIVE,
00893
NULL,
00894
NULL
00895 );
00896
00897 status =
NtCreateFile(
00898 &dgHandle,
00899 GENERIC_READ | GENERIC_WRITE,
00900 &objectAttributes,
00901 &ioStatusBlock,
00902
NULL,
00903 0,
00904 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
00905 FILE_OPEN,
00906 FILE_SYNCHRONOUS_IO_NONALERT,
00907
NULL,
00908 0
00909 );
00910
if ( !
NT_SUCCESS(status) ) {
00911 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to open datagram receiver: %x\n", status ));
00912
goto cleanup;
00913 }
00914
00915
00916
00917
00918
00919
00920
00921
#if defined(REMOTE_BOOT)
00922
if (LoaderBlock->
SetupLoaderBlock->
NetBootSecret)
00923
#endif // defined(REMOTE_BOOT)
00924
{
00925 PLMMR_RI_INITIALIZE_SECRET RbInit = (PLMMR_RI_INITIALIZE_SECRET)buffer;
00926
00927
ASSERT(LoaderBlock->
SetupLoaderBlock->
NetBootSecret !=
NULL);
00928 RtlCopyMemory(
00929 &RbInit->Secret,
00930 LoaderBlock->
SetupLoaderBlock->
NetBootSecret,
00931
sizeof(RI_SECRET));
00932
#if defined(REMOTE_BOOT)
00933
RbInit->UsePassword2 = LoaderBlock->
SetupLoaderBlock->NetBootUsePassword2;
00934
#endif // defined(REMOTE_BOOT)
00935
00936 status =
NtFsControlFile(
00937 RdrHandle,
00938
NULL,
00939
NULL,
00940
NULL,
00941 &ioStatusBlock,
00942 FSCTL_LMMR_RI_INITIALIZE_SECRET,
00943 buffer,
00944
sizeof(LMMR_RI_INITIALIZE_SECRET),
00945
NULL,
00946 0
00947 );
00948
00949
if (
NT_SUCCESS(status) ) {
00950 status = ioStatusBlock.Status;
00951 }
00952
if ( !
NT_SUCCESS(status) ) {
00953 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to FSCTL(RB initialize) redirector: %x\n", status ));
00954
goto cleanup;
00955 }
00956 }
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
RtlInitUnicodeString( &string,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ComputerName" );
00969
00970 InitializeObjectAttributes(
00971 &objectAttributes,
00972 &string,
00973 OBJ_CASE_INSENSITIVE,
00974
NULL,
00975
NULL
00976 );
00977
00978 status =
NtOpenKey( &keyHandle, KEY_ALL_ACCESS, &objectAttributes );
00979
if ( !
NT_SUCCESS(status) ) {
00980 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to open ComputerName key: %x\n", status ));
00981
goto cleanup;
00982 }
00983
00984
RtlInitUnicodeString( &string,
L"ComputerName" );
00985
00986 keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
00987 RtlZeroMemory(buffer, bufferLength);
00988
00989 status =
NtQueryValueKey(
00990 keyHandle,
00991 &string,
00992 KeyValuePartialInformation,
00993 keyValue,
00994 bufferLength,
00995 &length);
00996
00997
NtClose( keyHandle );
00998
if ( !
NT_SUCCESS(status) ) {
00999 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to query ComputerName value: %x\n", status ));
01000
goto cleanup;
01001 }
01002
01003
if ( !
RtlCreateUnicodeString(&computerName, (PWSTR)keyValue->Data) ) {
01004 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to create ComputerName string\n" ));
01005 status = STATUS_INSUFFICIENT_RESOURCES;
01006
goto cleanup;
01007 }
01008
01009 domainName.Length = 0;
01010
01011
RtlInitUnicodeString( &string,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\DomainName" );
01012
01013 InitializeObjectAttributes(
01014 &objectAttributes,
01015 &string,
01016 OBJ_CASE_INSENSITIVE,
01017
NULL,
01018
NULL
01019 );
01020
01021 status =
NtOpenKey( &keyHandle, KEY_ALL_ACCESS, &objectAttributes );
01022
if ( !
NT_SUCCESS(status) ) {
01023 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to open DomainName key: %x\n", status ));
01024 startDatagramReceiver =
FALSE;
01025 }
else {
01026
01027
RtlInitUnicodeString( &string,
L"DomainName" );
01028
01029 keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
01030 RtlZeroMemory(buffer, bufferLength);
01031
01032 status =
NtQueryValueKey(
01033 keyHandle,
01034 &string,
01035 KeyValuePartialInformation,
01036 keyValue,
01037 bufferLength,
01038 &length);
01039
01040
NtClose( keyHandle );
01041
if ( !
NT_SUCCESS(status) ) {
01042 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to query Domain value: %x\n", status ));
01043 startDatagramReceiver =
FALSE;
01044 }
else {
01045
if ( !
RtlCreateUnicodeString(&domainName, (PWSTR)keyValue->Data) ) {
01046 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to create DomainName string\n" ));
01047 status = STATUS_INSUFFICIENT_RESOURCES;
01048
goto cleanup;
01049 }
01050 startDatagramReceiver =
TRUE;
01051 }
01052 }
01053
01054
01055
01056
01057
01058 rrp->Type = ConfigInformation;
01059 rrp->Version = REQUEST_PACKET_VERSION;
01060
01061 rrp->Parameters.Start.RedirectorNameLength = computerName.Length;
01062 RtlCopyMemory(rrp->Parameters.Start.RedirectorName,
01063 computerName.Buffer,
01064 computerName.Length);
01065
01066 rrp->Parameters.Start.DomainNameLength = domainName.Length;
01067 RtlCopyMemory(((PUCHAR)rrp->Parameters.Start.RedirectorName) + computerName.Length,
01068 domainName.Buffer,
01069 domainName.Length);
01070
01071
RtlFreeUnicodeString(&computerName);
01072
RtlFreeUnicodeString(&domainName);
01073
01074 wkstaConfig.wki502_char_wait = 3600;
01075 wkstaConfig.wki502_maximum_collection_count = 16;
01076 wkstaConfig.wki502_collection_time = 250;
01077 wkstaConfig.wki502_keep_conn = 600;
01078 wkstaConfig.wki502_max_cmds = 5;
01079 wkstaConfig.wki502_sess_timeout = 45;
01080 wkstaConfig.wki502_siz_char_buf = 512;
01081 wkstaConfig.wki502_max_threads = 17;
01082 wkstaConfig.wki502_lock_quota = 6144;
01083 wkstaConfig.wki502_lock_increment = 10;
01084 wkstaConfig.wki502_lock_maximum = 500;
01085 wkstaConfig.wki502_pipe_increment = 10;
01086 wkstaConfig.wki502_pipe_maximum = 500;
01087 wkstaConfig.wki502_cache_file_timeout = 40;
01088 wkstaConfig.wki502_dormant_file_limit = 45;
01089 wkstaConfig.wki502_read_ahead_throughput = MAXULONG;
01090 wkstaConfig.wki502_num_mailslot_buffers = 3;
01091 wkstaConfig.wki502_num_srv_announce_buffers = 20;
01092 wkstaConfig.wki502_max_illegal_datagram_events = 5;
01093 wkstaConfig.wki502_illegal_datagram_event_reset_frequency = 60;
01094 wkstaConfig.wki502_log_election_packets =
FALSE;
01095 wkstaConfig.wki502_use_opportunistic_locking =
TRUE;
01096 wkstaConfig.wki502_use_unlock_behind =
TRUE;
01097 wkstaConfig.wki502_use_close_behind =
TRUE;
01098 wkstaConfig.wki502_buf_named_pipes =
TRUE;
01099 wkstaConfig.wki502_use_lock_read_unlock =
TRUE;
01100 wkstaConfig.wki502_utilize_nt_caching =
TRUE;
01101 wkstaConfig.wki502_use_raw_read =
TRUE;
01102 wkstaConfig.wki502_use_raw_write =
TRUE;
01103 wkstaConfig.wki502_use_write_raw_data =
TRUE;
01104 wkstaConfig.wki502_use_encryption =
TRUE;
01105 wkstaConfig.wki502_buf_files_deny_write =
TRUE;
01106 wkstaConfig.wki502_buf_read_only_files =
TRUE;
01107 wkstaConfig.wki502_force_core_create_mode =
TRUE;
01108 wkstaConfig.wki502_use_512_byte_max_transfer =
FALSE;
01109
01110 status =
NtFsControlFile(
01111 RdrHandle,
01112
NULL,
01113
NULL,
01114
NULL,
01115 &ioStatusBlock,
01116 FSCTL_LMR_START | 0x80000000,
01117 rrp,
01118
sizeof(LMR_REQUEST_PACKET) +
01119 rrp->Parameters.Start.RedirectorNameLength +
01120 rrp->Parameters.Start.DomainNameLength,
01121 &wkstaConfig,
01122
sizeof(wkstaConfig)
01123 );
01124
01125
if (
NT_SUCCESS(status) ) {
01126 status = ioStatusBlock.Status;
01127 }
01128
if ( !
NT_SUCCESS(status) ) {
01129 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to FSCTL(start) redirector: %x\n", status ));
01130
goto cleanup;
01131 }
01132
01133
if (startDatagramReceiver) {
01134
01135
01136
01137
01138
01139 drrp->Version = LMDR_REQUEST_PACKET_VERSION;
01140
01141 drrp->Parameters.Start.NumberOfMailslotBuffers = 16;
01142 drrp->Parameters.Start.NumberOfServerAnnounceBuffers = 20;
01143 drrp->Parameters.Start.IllegalDatagramThreshold = 5;
01144 drrp->Parameters.Start.EventLogResetFrequency = 60;
01145 drrp->Parameters.Start.LogElectionPackets =
FALSE;
01146
01147 drrp->Parameters.Start.IsLanManNt =
FALSE;
01148
01149 status =
NtDeviceIoControlFile(
01150 dgHandle,
01151
NULL,
01152
NULL,
01153
NULL,
01154 &ioStatusBlock,
01155 IOCTL_LMDR_START,
01156 drrp,
01157
sizeof(LMDR_REQUEST_PACKET),
01158
NULL,
01159 0
01160 );
01161
01162
if (
NT_SUCCESS(status) ) {
01163 status = ioStatusBlock.Status;
01164 }
01165
01166
NtClose( dgHandle );
01167 dgHandle =
NULL;
01168
01169
if ( !
NT_SUCCESS(status) ) {
01170 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to IOCTL(start) datagram receiver: %x\n", status ));
01171
goto cleanup;
01172 }
01173
01174 }
else {
01175
01176
NtClose( dgHandle );
01177 dgHandle =
NULL;
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 status =
NtFsControlFile(
01189 RdrHandle,
01190
NULL,
01191
NULL,
01192
NULL,
01193 &ioStatusBlock,
01194 FSCTL_LMR_BIND_TO_TRANSPORT | 0x80000000,
01195
NULL,
01196 0,
01197
NULL,
01198 0
01199 );
01200
01201
if (
NT_SUCCESS(status) ) {
01202 status = ioStatusBlock.Status;
01203 }
01204
01205
if ( !
NT_SUCCESS(status) ) {
01206 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to FSCTL(bind) redirector: %x\n", status ));
01207
goto cleanup;
01208 }
01209 }
01210
01211
#if defined(REMOTE_BOOT)
01212
if (((LoaderBlock->
SetupLoaderBlock->
Flags &
SETUPBLK_FLAGS_IS_TEXTMODE) == 0) &&
01213 ((LoaderBlock->
SetupLoaderBlock->
Flags & SETUPBLK_FLAGS_FORMAT_NEEDED) == 0)) {
01214
01215
01216
01217
01218
01219
01220 IopGetHarddiskInfo(NetHDCSCPartition);
01221
01222
01223
01224
01225
01226
01227
01228
01229 status =
NtFsControlFile(
01230 RdrHandle,
01231
NULL,
01232
NULL,
01233
NULL,
01234 &ioStatusBlock,
01235 FSCTL_LMR_START_RBR,
01236 NetHDCSCPartition,
01237 wcslen(NetHDCSCPartition) *
sizeof(WCHAR),
01238
NULL,
01239 0
01240 );
01241
01242
if (
NT_SUCCESS(status) ) {
01243 status = ioStatusBlock.Status;
01244 }
01245
01246
if ( !
NT_SUCCESS(status) ) {
01247 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to FSCTL(RBR) redirector: %x\n", status ));
01248 }
01249 }
01250
01251
if ( (LoaderBlock->
SetupLoaderBlock->
Flags & SETUPBLK_FLAGS_DISCONNECTED) == 0 )
01252
#endif // defined(REMOTE_BOOT)
01253
{
01254
01255
01256
01257
01258
01259
01260
01261
01262 interval.QuadPart = -500 * 1000 * 10;
01263 enumerateAttempts = 0;
01264
01265
while (
TRUE) {
01266
01267
KeDelayExecutionThread(
KernelMode,
FALSE, &interval);
01268
01269 RtlZeroMemory(rrp,
sizeof(LMR_REQUEST_PACKET));
01270
01271 rrp->Type = EnumerateTransports;
01272 rrp->Version = REQUEST_PACKET_VERSION;
01273
01274 status =
NtFsControlFile(
01275 RdrHandle,
01276
NULL,
01277
NULL,
01278
NULL,
01279 &ioStatusBlock,
01280 FSCTL_LMR_ENUMERATE_TRANSPORTS,
01281 rrp,
01282
sizeof(LMR_REQUEST_PACKET),
01283 &wkstaTransportInfo,
01284
sizeof(wkstaTransportInfo)
01285 );
01286
01287
if (
NT_SUCCESS(status) ) {
01288 status = ioStatusBlock.Status;
01289 }
01290
if ( !
NT_SUCCESS(status) ) {
01291
01292 }
else if (rrp->Parameters.Get.TotalBytesNeeded == 0) {
01293
01294 }
else {
01295
break;
01296 }
01297
01298 ++enumerateAttempts;
01299
01300
if (enumerateAttempts == 5) {
01301 KdPrint((
"IopStartNetworkForRemoteBoot: Redirector didn't start\n" ));
01302 status = STATUS_REDIRECTOR_NOT_STARTED;
01303
goto cleanup;
01304 }
01305
01306 interval.QuadPart *= 2;
01307
01308 }
01309 }
01310
01311
01312
01313
01314
01315
#if defined(REMOTE_BOOT)
01316
IopEnableRemoteBootSecurity(LoaderBlock);
01317
#endif // defined(REMOTE_BOOT)
01318
IopSetDefaultGateway(LoaderBlock->
SetupLoaderBlock->
DefaultRouter);
01319
IopCacheNetbiosNameForIpAddress(LoaderBlock);
01320
01321
#if defined(REMOTE_BOOT)
01322
01323
01324
01325
01326
01327
if (((LoaderBlock->
SetupLoaderBlock->
Flags &
SETUPBLK_FLAGS_IS_TEXTMODE) == 0) &&
01328 ((LoaderBlock->
SetupLoaderBlock->
Flags & SETUPBLK_FLAGS_FORMAT_NEEDED) == 0)
01329
#if 0
01330
&& ((LoaderBlock->
SetupLoaderBlock->
Flags & SETUPBLK_FLAGS_DISABLE_CSC) != 0)
01331
#endif
01332
) {
01333
01334 wcstombs(buffer, NetHDCSCPartition, wcslen(NetHDCSCPartition) + 1);
01335 strcat(buffer, REMOTE_BOOT_IMIRROR_PATH_A REMOTE_BOOT_CSC_SUBDIR_A);
01336
01337 status = IopInitCsc( buffer );
01338
01339
01340
01341
01342
01343
01344
if (
NT_SUCCESS(status) ) {
01345
01346
if (StartCsc == FLUSH_CSC ) {
01347
01348
if ((LoaderBlock->
SetupLoaderBlock->
Flags & SETUPBLK_FLAGS_DISCONNECTED) == 0) {
01349
01350
01351
01352
01353
01354 status = IopResetCsc( buffer );
01355
01356
if ( !
NT_SUCCESS(status) ) {
01357 KdPrint((
"IopStartNetworkForRemoteBoot: reset of Csc failed %x\n", status));
01358 }
01359 }
else {
01360 IoCscInitializationFailed =
TRUE;
01361 }
01362 }
else if ((LoaderBlock->
SetupLoaderBlock->
Flags & SETUPBLK_FLAGS_PIN_NET_DRIVER) &&
01363 (LoaderBlock->
SetupLoaderBlock->
NetbootCardDriverName[0] !=
L'\0')) {
01364
01365
01366
01367
01368
01369
01370
01371 pinNetDriver =
TRUE;
01372 }
01373 }
01374
01375
if ( !
NT_SUCCESS(status) ) {
01376 KdPrint((
"IopStartNetworkForRemoteBoot: initialization of Csc failed %x\n", status));
01377 IoCscInitializationFailed =
TRUE;
01378 SharedUserData->SystemFlags |= SYSTEM_FLAG_DISKLESS_CLIENT;
01379 }
01380
01381 }
else {
01382 IoCscInitializationFailed =
TRUE;
01383 SharedUserData->SystemFlags |= SYSTEM_FLAG_DISKLESS_CLIENT;
01384 }
01385
#endif // defined(REMOTE_BOOT)
01386
01387
IopAssignNetworkDriveLetter(LoaderBlock);
01388
01389
#if defined(REMOTE_BOOT)
01390
if (pinNetDriver) {
01391
01392
01393
01394
01395
01396
01397
01398 HANDLE driverHandle =
NULL;
01399 PWCHAR fullDriverName;
01400
01401 fullDriverName = (PWCHAR)
ExAllocatePoolWithTag(
01402
NonPagedPool,
01403
sizeof(
L"\\SystemRoot\\System32\\Drivers\\" ) +
01404
sizeof( LoaderBlock->
SetupLoaderBlock->
NetbootCardDriverName ),
01405 'bRoI'
01406 );
01407
01408
if (fullDriverName !=
NULL) {
01409
01410 wcscpy(fullDriverName,
L"\\SystemRoot\\System32\\Drivers\\");
01411 wcscat(fullDriverName, LoaderBlock->
SetupLoaderBlock->
NetbootCardDriverName);
01412
01413
RtlInitUnicodeString( &string, fullDriverName );
01414
01415 InitializeObjectAttributes(
01416 &objectAttributes,
01417 &string,
01418 OBJ_CASE_INSENSITIVE,
01419
NULL,
01420
NULL
01421 );
01422
01423 status =
NtCreateFile(
01424 &driverHandle,
01425 GENERIC_READ,
01426 &objectAttributes,
01427 &ioStatusBlock,
01428
NULL,
01429 FILE_ATTRIBUTE_NORMAL,
01430 FILE_SHARE_READ,
01431 FILE_OPEN,
01432 FILE_SYNCHRONOUS_IO_NONALERT,
01433
NULL,
01434 0
01435 );
01436
if ( !
NT_SUCCESS(status) ) {
01437
01438
01439
01440
01441
01442 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to open new net driver: 0x%x\n", status ));
01443 }
01444
if (driverHandle !=
NULL) {
01445
NtClose( driverHandle );
01446 }
01447
01448
ExFreePool( fullDriverName );
01449
01450 }
else {
01451
01452
01453
01454
01455
01456 KdPrint((
"IopStartNetworkForRemoteBoot: Unable to allocate buffer to pin netcard driver\n" ));
01457 }
01458 }
01459
01460 leaveRdrHandleOpen =
TRUE;
01461
#endif // defined(REMOTE_BOOT)
01462
01463 cleanup:
01464
01465
RtlFreeUnicodeString( &computerName );
01466
RtlFreeUnicodeString( &domainName );
01467
#if defined(REMOTE_BOOT)
01468
if ( NetHDCSCPartition !=
NULL ) {
01469
ExFreePool( NetHDCSCPartition );
01470 }
01471
#else
01472
if ( buffer !=
NULL ) {
01473
ExFreePool( buffer );
01474 }
01475
#endif // defined(REMOTE_BOOT)
01476
01477
if ( dgHandle !=
NULL ) {
01478
NtClose( dgHandle );
01479 }
01480
01481
#if defined(REMOTE_BOOT)
01482
01483
01484
01485
01486
if ( !leaveRdrHandleOpen && (RdrHandle !=
NULL) ) {
01487
NtClose( RdrHandle );
01488 RdrHandle =
NULL;
01489 }
01490
#endif // defined(REMOTE_BOOT)
01491
01492
return status;
01493 }
01494
01495
01496
#if defined(REMOTE_BOOT)
01497
VOID
01498 IopShutdownCsc(
01499 )
01500 {
01501
NTSTATUS status;
01502 IO_STATUS_BLOCK ioStatusBlock;
01503 SHADOWINFO shadowInfo;
01504
01505
if ( RdrHandle !=
NULL ) {
01506
01507
KeAttachProcess( RdrHandleProcess );
01508
01509 RtlZeroMemory( &shadowInfo,
sizeof(shadowInfo) );
01510 shadowInfo.uStatus = 0x0001;
01511 shadowInfo.uOp = 1;
01512
01513 status =
NtDeviceIoControlFile(
01514 RdrHandle,
01515 NULL,
01516 NULL,
01517 NULL,
01518 &ioStatusBlock,
01519 IOCTL_SWITCHES,
01520 &shadowInfo,
01521 0,
01522 NULL,
01523 0
01524 );
01525
#if DBG
01526
if (
NT_SUCCESS(status) ) {
01527 status = ioStatusBlock.Status;
01528 }
01529
01530
if ( !
NT_SUCCESS(status) ) {
01531 KdPrint((
"IopShutdownCsc: %x\n", status ));
01532 }
01533
#endif
01534
NtClose( RdrHandle );
01535 RdrHandle =
NULL;
01536
01537
KeDetachProcess();
01538 }
01539
01540
return;
01541 }
01542
#endif // defined(REMOTE_BOOT)
01543
01544
01545
VOID
01546 IopAssignNetworkDriveLetter (
01547
PLOADER_PARAMETER_BLOCK LoaderBlock
01548 )
01549 {
01550 PUCHAR p;
01551 PUCHAR q;
01552 UCHAR ntName[128];
01553 STRING ansiString;
01554 UNICODE_STRING unicodeString;
01555 UNICODE_STRING unicodeString2;
01556
NTSTATUS status;
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
if ((LoaderBlock->
SetupLoaderBlock->
Flags & (
SETUPBLK_FLAGS_REMOTE_INSTALL |
01569
SETUPBLK_FLAGS_SYSPREP_INSTALL)) != 0) {
01570
RtlInitUnicodeString( &unicodeString2,
L"\\DosDevices\\X:");
01571 }
else {
01572
RtlInitUnicodeString( &unicodeString2,
L"\\DosDevices\\C:");
01573 }
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589 p = strrchr( LoaderBlock->
NtBootPathName,
'\\' );
01590
if ( (p !=
NULL) && (*(p+1) == 0) ) {
01591
01592
01593
01594
01595
01596
01597 q = p;
01598 *q = 0;
01599 p = strrchr( LoaderBlock->
NtBootPathName,
'\\' );
01600 *q =
'\\';
01601 }
01602
if ( p ==
NULL ) {
01603 KdPrint((
"IopAssignNetworkDriveLetter: malformed NtBootPathName: %s\n", LoaderBlock->
NtBootPathName ));
01604
KeBugCheck( ASSIGN_DRIVE_LETTERS_FAILED );
01605 }
01606 *p = 0;
01607
01608 strcpy( ntName,
"\\Device\\LanmanRedirector");
01609 strcat( ntName, LoaderBlock->
NtBootPathName );
01610
01611
RtlInitAnsiString( &ansiString, ntName );
01612
RtlAnsiStringToUnicodeString( &unicodeString, &ansiString,
TRUE );
01613
01614 status =
IoCreateSymbolicLink(&unicodeString2, &unicodeString);
01615
if (!
NT_SUCCESS(status)) {
01616 KdPrint((
"IopAssignNetworkDriveLetter: unable to create DOS link for redirected boot drive: %x\n", status ));
01617
KeBugCheck( ASSIGN_DRIVE_LETTERS_FAILED );
01618 }
01619
01620
01621
RtlFreeUnicodeString( &unicodeString );
01622
01623 *p =
'\\';
01624
01625
return;
01626 }
01627
01628
01629
#if defined(REMOTE_BOOT)
01630
VOID
01631 IopEnableRemoteBootSecurity (
01632
PLOADER_PARAMETER_BLOCK LoaderBlock
01633 )
01634 {
01635 UNICODE_STRING IpsecString;
01636
NTSTATUS status;
01637 HANDLE handle;
01638 OBJECT_ATTRIBUTES objectAttributes;
01639 IO_STATUS_BLOCK ioStatusBlock;
01640 UCHAR policyBuffer[
sizeof(IPSEC_SET_POLICY) +
sizeof(IPSEC_POLICY_INFO)];
01641 PIPSEC_SET_POLICY setPolicy = (PIPSEC_SET_POLICY)policyBuffer;
01642 IPSEC_FILTER outboundFilter;
01643 IPSEC_FILTER inboundFilter;
01644 IPSEC_SET_SPI setSpi;
01645 UCHAR saBuffer[
sizeof(IPSEC_ADD_UPDATE_SA) + (6 *
sizeof(ULONG))];
01646 PIPSEC_ADD_UPDATE_SA addUpdateSa;
01647
01648
01649
if ((LoaderBlock->
SetupLoaderBlock->
Flags & SETUPBLK_FLAGS_IPSEC_ENABLED) == 0) {
01650
return;
01651 }
01652
01653
RtlInitUnicodeString( &IpsecString, DD_IPSEC_DEVICE_NAME );
01654
01655 InitializeObjectAttributes(
01656 &objectAttributes,
01657 &IpsecString,
01658 OBJ_CASE_INSENSITIVE,
01659 NULL,
01660 NULL
01661 );
01662
01663 status =
NtCreateFile(
01664 &handle,
01665 GENERIC_READ | GENERIC_WRITE,
01666 &objectAttributes,
01667 &ioStatusBlock,
01668 NULL,
01669 0,
01670 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
01671 FILE_OPEN,
01672 FILE_SYNCHRONOUS_IO_NONALERT,
01673 NULL,
01674 0
01675 );
01676
if ( !
NT_SUCCESS(status) ) {
01677 KdPrint((
"IopEnableRemoteBootSecurity: Unable to open IPSEC: %x\n", status ));
01678
return;
01679 }
01680
01681
01682
01683
01684
01685
01686 RtlZeroMemory(&outboundFilter,
sizeof(IPSEC_FILTER));
01687 RtlZeroMemory(&inboundFilter,
sizeof(IPSEC_FILTER));
01688
01689 outboundFilter.SrcAddr = LoaderBlock->
SetupLoaderBlock->
IpAddress;
01690 outboundFilter.SrcMask = 0xffffffff;
01691 outboundFilter.DestAddr = LoaderBlock->
SetupLoaderBlock->
ServerIpAddress;
01692 outboundFilter.DestMask = 0xffffffff;
01693
01694 outboundFilter.Protocol = 0x6;
01695
01696 inboundFilter.SrcAddr = LoaderBlock->
SetupLoaderBlock->
ServerIpAddress;
01697 inboundFilter.SrcMask = 0xffffffff;
01698
01699 inboundFilter.DestAddr = LoaderBlock->
SetupLoaderBlock->
IpAddress;
01700 inboundFilter.DestMask = 0xffffffff;
01701 inboundFilter.Protocol = 0x6;
01702
01703 RtlZeroMemory(setPolicy,
sizeof(policyBuffer));
01704
01705 setPolicy->NumEntries = 2;
01706 setPolicy->pInfo[0].Index = 1;
01707 setPolicy->pInfo[0].AssociatedFilter = outboundFilter;
01708 setPolicy->pInfo[1].Index = 2;
01709 setPolicy->pInfo[1].AssociatedFilter = inboundFilter;
01710
01711 status =
NtDeviceIoControlFile(
01712 handle,
01713 NULL,
01714 NULL,
01715 NULL,
01716 &ioStatusBlock,
01717 IOCTL_IPSEC_SET_POLICY,
01718 setPolicy,
01719
sizeof(policyBuffer),
01720 NULL,
01721 0
01722 );
01723
01724
if ( !
NT_SUCCESS(status) ) {
01725 KdPrint((
"IopEnableRemoteBootSecurity: Unable to IOCTL_IPSEC_SET_POLICY: %x\n", status ));
01726
return;
01727 }
01728
01729
01730
01731
01732
01733 setSpi.Context = 0;
01734 setSpi.InstantiatedFilter = inboundFilter;
01735 setSpi.SPI = LoaderBlock->
SetupLoaderBlock->IpsecInboundSpi;
01736
01737 status =
NtDeviceIoControlFile(
01738 handle,
01739 NULL,
01740 NULL,
01741 NULL,
01742 &ioStatusBlock,
01743 IOCTL_IPSEC_SET_SPI,
01744 &setSpi,
01745
sizeof(IPSEC_SET_SPI),
01746 &setSpi,
01747
sizeof(IPSEC_SET_SPI)
01748 );
01749
01750
if ( !
NT_SUCCESS(status) ) {
01751 KdPrint((
"IopEnableRemoteBootSecurity: Unable to IOCTL_IPSEC_SET_SPI: %x\n", status ));
01752
return;
01753 }
01754
01755
01756
01757
01758
01759
01760 addUpdateSa = (PIPSEC_ADD_UPDATE_SA)saBuffer;
01761 memset(addUpdateSa, 0,
sizeof(saBuffer));
01762
01763 addUpdateSa->SAInfo.Context = setSpi.Context;
01764 addUpdateSa->SAInfo.NumSAs = 1;
01765 addUpdateSa->SAInfo.InstantiatedFilter = outboundFilter;
01766 addUpdateSa->SAInfo.SecAssoc[0].Operation = Encrypt;
01767 addUpdateSa->SAInfo.SecAssoc[0].SPI = LoaderBlock->
SetupLoaderBlock->IpsecOutboundSpi;
01768 addUpdateSa->SAInfo.SecAssoc[0].IntegrityAlgo.algoIdentifier = IPSEC_AH_MD5;
01769 addUpdateSa->SAInfo.SecAssoc[0].IntegrityAlgo.algoKeylen = 4 *
sizeof(ULONG);
01770 addUpdateSa->SAInfo.SecAssoc[0].ConfAlgo.algoIdentifier = IPSEC_ESP_DES;
01771 addUpdateSa->SAInfo.SecAssoc[0].ConfAlgo.algoKeylen = 2 *
sizeof(ULONG);
01772
01773 addUpdateSa->SAInfo.KeyLen = 6 *
sizeof(ULONG);
01774 memcpy(addUpdateSa->SAInfo.KeyMat, &LoaderBlock->
SetupLoaderBlock->IpsecSessionKey,
sizeof(ULONG));
01775 memcpy(addUpdateSa->SAInfo.KeyMat+
sizeof(ULONG), &LoaderBlock->
SetupLoaderBlock->IpsecSessionKey,
sizeof(ULONG));
01776 memcpy(addUpdateSa->SAInfo.KeyMat+(2*
sizeof(ULONG)), &LoaderBlock->
SetupLoaderBlock->IpsecSessionKey,
sizeof(ULONG));
01777 memcpy(addUpdateSa->SAInfo.KeyMat+(3*
sizeof(ULONG)), &LoaderBlock->
SetupLoaderBlock->IpsecSessionKey,
sizeof(ULONG));
01778 memcpy(addUpdateSa->SAInfo.KeyMat+(4*
sizeof(ULONG)), &LoaderBlock->
SetupLoaderBlock->IpsecSessionKey,
sizeof(ULONG));
01779 memcpy(addUpdateSa->SAInfo.KeyMat+(5*
sizeof(ULONG)), &LoaderBlock->
SetupLoaderBlock->IpsecSessionKey,
sizeof(ULONG));
01780
01781 status =
NtDeviceIoControlFile(
01782 handle,
01783 NULL,
01784 NULL,
01785 NULL,
01786 &ioStatusBlock,
01787 IOCTL_IPSEC_ADD_SA,
01788 addUpdateSa,
01789 FIELD_OFFSET(IPSEC_ADD_UPDATE_SA, SAInfo.KeyMat[0]) + addUpdateSa->SAInfo.KeyLen,
01790 NULL,
01791 0
01792 );
01793
01794
if ( !
NT_SUCCESS(status) ) {
01795 KdPrint((
"IopEnableRemoteBootSecurity: Unable to IOCTL_IPSEC_ADD_SA: %x\n", status ));
01796
return;
01797 }
01798
01799
01800
01801
01802
01803
01804
if (addUpdateSa->SAInfo.SecAssoc[0].Operation != None) {
01805
01806 addUpdateSa->SAInfo.SecAssoc[0].SPI = LoaderBlock->
SetupLoaderBlock->IpsecInboundSpi;
01807 addUpdateSa->SAInfo.InstantiatedFilter = inboundFilter;
01808
01809 status =
NtDeviceIoControlFile(
01810 handle,
01811 NULL,
01812 NULL,
01813 NULL,
01814 &ioStatusBlock,
01815 IOCTL_IPSEC_UPDATE_SA,
01816 addUpdateSa,
01817 FIELD_OFFSET(IPSEC_ADD_UPDATE_SA, SAInfo.KeyMat[0]) + addUpdateSa->SAInfo.KeyLen,
01818 NULL,
01819 0
01820 );
01821
01822
if ( !
NT_SUCCESS(status) ) {
01823 KdPrint((
"IopEnableRemoteBootSecurity: Unable to IOCTL_IPSEC_UPDATE_SA: %x\n", status ));
01824
return;
01825 }
01826 }
01827
01828
NtClose( handle );
01829
01830 }
01831
#endif // defined(REMOTE_BOOT)
01832
01833
NTSTATUS
01834 IopStartTcpIpForRemoteBoot (
01835
PLOADER_PARAMETER_BLOCK LoaderBlock
01836 )
01837 {
01838 UNICODE_STRING IpString;
01839
NTSTATUS status = STATUS_SUCCESS;
01840 HANDLE handle;
01841 OBJECT_ATTRIBUTES objectAttributes;
01842 IO_STATUS_BLOCK ioStatusBlock;
01843 IP_SET_ADDRESS_REQUEST IpRequest;
01844
01845
RtlInitUnicodeString( &IpString, DD_IP_DEVICE_NAME );
01846
01847 InitializeObjectAttributes(
01848 &objectAttributes,
01849 &IpString,
01850 OBJ_CASE_INSENSITIVE,
01851
NULL,
01852
NULL
01853 );
01854
01855 IpRequest.Context = (
USHORT)2;
01856 IpRequest.Address = LoaderBlock->
SetupLoaderBlock->
IpAddress;
01857 IpRequest.SubnetMask = LoaderBlock->
SetupLoaderBlock->
SubnetMask;
01858
01859 status =
NtCreateFile(
01860 &handle,
01861 GENERIC_READ | GENERIC_WRITE,
01862 &objectAttributes,
01863 &ioStatusBlock,
01864
NULL,
01865 0,
01866 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
01867 FILE_OPEN,
01868 FILE_SYNCHRONOUS_IO_NONALERT,
01869
NULL,
01870 0
01871 );
01872
if ( !
NT_SUCCESS(status) ) {
01873 KdPrint((
"IopStartTcpIpForRemoteBoot: Unable to open IP: %x\n", status ));
01874
goto cleanup;
01875 }
01876
01877 status =
NtDeviceIoControlFile(
01878 handle,
01879
NULL,
01880
NULL,
01881
NULL,
01882 &ioStatusBlock,
01883 IOCTL_IP_SET_ADDRESS_DUP,
01884 &IpRequest,
01885
sizeof(IP_SET_ADDRESS_REQUEST),
01886
NULL,
01887 0
01888 );
01889
01890
NtClose( handle );
01891
01892
if ( !
NT_SUCCESS(status) ) {
01893 KdPrint((
"IopStartTcpIpForRemoteBoot: Unable to IOCTL IP: %x\n", status ));
01894
goto cleanup;
01895 }
01896
01897 cleanup:
01898
01899
return status;
01900 }
01901
01902 BOOLEAN
01903 IopIsRemoteBootCard(
01904 IN
PDEVICE_NODE DeviceNode,
01905 IN
PLOADER_PARAMETER_BLOCK LoaderBlock,
01906 IN PWCHAR HwIds
01907 )
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935 {
01936
PSETUP_LOADER_BLOCK setupLoaderBlock;
01937 PWCHAR curHwId;
01938
01939
01940
01941
01942
01943
01944 setupLoaderBlock = LoaderBlock->SetupLoaderBlock;
01945
01946
01947
01948
01949
01950 curHwId = HwIds;
01951
01952
while (*curHwId !=
L'\0') {
01953
if (wcscmp(curHwId, setupLoaderBlock->
NetbootCardHardwareId) == 0) {
01954
01955 ULONG
BusNumber, SlotNumber;
01956
01957
BusNumber = (ULONG)((((PNET_CARD_INFO)setupLoaderBlock->
NetbootCardInfo)->pci.BusDevFunc) >> 8);
01958 SlotNumber = (ULONG)(((((PNET_CARD_INFO)setupLoaderBlock->
NetbootCardInfo)->pci.BusDevFunc) & 0xf8) >> 3);
01959
01960 KdPrint((
"IopIsRemoteBootCard: FOUND %ws\n", setupLoaderBlock->
NetbootCardHardwareId));
01961
if ((DeviceNode->ResourceRequirements->BusNumber !=
BusNumber) ||
01962 (DeviceNode->ResourceRequirements->SlotNumber != SlotNumber)) {
01963 KdPrint((
"IopIsRemoteBootCard: ignoring non-matching card:\n"));
01964 KdPrint((
" devnode bus %d, busdevfunc bus %d\n",
01965 DeviceNode->ResourceRequirements->BusNumber,
01966
BusNumber));
01967 KdPrint((
" devnode slot %d, busdevfunc slot %d\n",
01968 DeviceNode->ResourceRequirements->SlotNumber,
01969 SlotNumber));
01970
return FALSE;
01971 }
else {
01972
return TRUE;
01973 }
01974 }
01975 curHwId += (wcslen(curHwId) + 1);
01976 }
01977
01978
return FALSE;
01979 }
01980
01981
NTSTATUS
01982 IopSetupRemoteBootCard(
01983 IN
PLOADER_PARAMETER_BLOCK LoaderBlock,
01984 IN HANDLE UniqueIdHandle,
01985 IN PUNICODE_STRING UnicodeDeviceInstance
01986 )
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014 {
02015
PSETUP_LOADER_BLOCK setupLoaderBlock;
02016 UNICODE_STRING unicodeName, pnpInstanceId, keyName;
02017 HANDLE tmpHandle;
02018 HANDLE parametersHandle =
NULL;
02019 HANDLE currentControlSetHandle =
NULL;
02020 HANDLE remoteBootHandle =
NULL;
02021 HANDLE instanceHandle =
NULL;
02022 PWCHAR componentIdBuffer, curComponentIdLoc;
02023 PCHAR registryList;
02024 ULONG componentIdLength;
02025 WCHAR tempNameBuffer[32];
02026 WCHAR tempValueBuffer[128];
02027
NTSTATUS status;
02028 ULONG tmpValue, length;
02029 PKEY_VALUE_PARTIAL_INFORMATION keyValue;
02030 PKEY_VALUE_BASIC_INFORMATION keyValueBasic;
02031 UCHAR dataBuffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + 128];
02032 ULONG enumerateIndex;
02033 OBJECT_ATTRIBUTES objectAttributes;
02034 ULONG disposition;
02035
02036
02037
02038
02039
02040
02041
02042
if (
IopRemoteBootCardInitialized) {
02043
return STATUS_SUCCESS;
02044 }
02045
02046
02047
02048
02049
02050
02051 setupLoaderBlock = LoaderBlock->SetupLoaderBlock;
02052
02053
02054
02055
02056
02057 status =
IopOpenRegistryKey(¤tControlSetHandle,
02058
NULL,
02059 &
CmRegistryMachineSystemCurrentControlSet,
02060 KEY_ALL_ACCESS,
02061
FALSE
02062 );
02063
02064
if (!
NT_SUCCESS(status)) {
02065
goto cleanup;
02066 }
02067
02068
02069
02070
02071
02072 PiWstrToUnicodeString(&unicodeName,
L"Control\\RemoteBoot");
02073
02074 InitializeObjectAttributes(&objectAttributes,
02075 &unicodeName,
02076 OBJ_CASE_INSENSITIVE,
02077 currentControlSetHandle,
02078 (PSECURITY_DESCRIPTOR)
NULL
02079 );
02080
02081 status = ZwCreateKey(&remoteBootHandle,
02082 KEY_ALL_ACCESS,
02083 &objectAttributes,
02084 0,
02085 (PUNICODE_STRING)
NULL,
02086 0,
02087 &disposition
02088 );
02089
02090
if (!
NT_SUCCESS(status)) {
02091
goto cleanup;
02092 }
02093
02094
02095
02096
02097
02098
02099
02100
02101 PiWstrToUnicodeString(&unicodeName,
L"Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\{54C7D140-09EF-11D1-B25A-F5FE627ED95E}");
02102
02103 InitializeObjectAttributes(&objectAttributes,
02104 &unicodeName,
02105 OBJ_CASE_INSENSITIVE,
02106 currentControlSetHandle,
02107 (PSECURITY_DESCRIPTOR)
NULL
02108 );
02109
02110 status = ZwCreateKey(&instanceHandle,
02111 KEY_ALL_ACCESS,
02112 &objectAttributes,
02113 0,
02114 (PUNICODE_STRING)
NULL,
02115 0,
02116 &disposition
02117 );
02118
02119
if (
NT_SUCCESS(status)) {
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129 PiWstrToUnicodeString(&unicodeName,
L"PnPInstanceID");
02130 keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)dataBuffer;
02131 RtlZeroMemory(dataBuffer,
sizeof(dataBuffer));
02132
02133 status = ZwQueryValueKey(
02134 instanceHandle,
02135 &unicodeName,
02136 KeyValuePartialInformation,
02137 keyValue,
02138
sizeof(dataBuffer),
02139 &length);
02140
02141
02142
02143
02144
02145
02146
02147
if ((
NT_SUCCESS(status)) &&
02148 (keyValue->Type == REG_SZ)) {
02149
02150
RtlInitUnicodeString(&pnpInstanceId, (PWSTR)(keyValue->Data));
02151
02152
if (
RtlEqualUnicodeString(UnicodeDeviceInstance, &pnpInstanceId,
TRUE)) {
02153
02154
02155
02156
02157
02158 PiWstrToUnicodeString(&unicodeName,
L"NetCardInfo");
02159 RtlZeroMemory(dataBuffer,
sizeof(dataBuffer));
02160
02161 status = ZwQueryValueKey(
02162 remoteBootHandle,
02163 &unicodeName,
02164 KeyValuePartialInformation,
02165 keyValue,
02166
sizeof(dataBuffer),
02167 &length);
02168
02169
if ((
NT_SUCCESS(status)) &&
02170 (keyValue->Type == REG_BINARY) &&
02171 (keyValue->DataLength ==
sizeof(NET_CARD_INFO)) &&
02172 (memcmp(keyValue->Data, setupLoaderBlock->
NetbootCardInfo,
sizeof(NET_CARD_INFO)) == 0)) {
02173
02174
02175
02176
02177
02178 status = STATUS_SUCCESS;
02179
goto cleanup;
02180
02181 }
02182 }
02183 }
02184 }
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_SERVICE);
02198 ZwSetValueKey(UniqueIdHandle,
02199 &unicodeName,
02200
TITLE_INDEX_VALUE,
02201 REG_SZ,
02202 setupLoaderBlock->
NetbootCardServiceName,
02203 (wcslen(setupLoaderBlock->
NetbootCardServiceName) + 1) *
sizeof(WCHAR)
02204 );
02205
02206
02207
02208
02209
02210 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_CLASSGUID);
02211 ZwSetValueKey(UniqueIdHandle,
02212 &unicodeName,
02213
TITLE_INDEX_VALUE,
02214 REG_SZ,
02215
L"{4D36E972-E325-11CE-BFC1-08002BE10318}",
02216
sizeof(
L"{4D36E972-E325-11CE-BFC1-08002BE10318}")
02217 );
02218
02219
02220
02221
02222
02223 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_DRIVER);
02224 ZwSetValueKey(UniqueIdHandle,
02225 &unicodeName,
02226
TITLE_INDEX_VALUE,
02227 REG_SZ,
02228
L"{4D36E972-E325-11CE-BFC1-08002BE10318}\\0000",
02229
sizeof(
L"{4D36E972-E325-11CE-BFC1-08002BE10318}\\0000")
02230 );
02231
02232
#ifdef REMOTE_BOOT
02233
02234
02235
02236
02237
02238 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_CONFIG_FLAGS);
02239
02240 keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)dataBuffer;
02241 RtlZeroMemory(dataBuffer,
sizeof(dataBuffer));
02242
02243 status = ZwQueryValueKey(UniqueIdHandle,
02244 &unicodeName,
02245 KeyValuePartialInformation,
02246 keyValue,
02247
sizeof(dataBuffer),
02248 &length);
02249
02250
if ((
NT_SUCCESS(status)) &&
02251 (keyValue->Type == REG_DWORD)) {
02252
02253
02254
02255 tmpValue = (*(PULONG)keyValue->Data) | CONFIGFLAG_NETBOOT_CARD;
02256 }
else {
02257 tmpValue = CONFIGFLAG_NETBOOT_CARD;
02258 }
02259
02260 ZwSetValueKey(UniqueIdHandle,
02261 &unicodeName,
02262
TITLE_INDEX_VALUE,
02263 REG_DWORD,
02264 &tmpValue,
02265
sizeof(tmpValue)
02266 );
02267
#endif
02268
02269
02270
02271
02272
02273
02274
02275 status =
IopOpenRegistryKey(&tmpHandle,
02276
NULL,
02277 &
CmRegistryMachineSystemCurrentControlSetControlClass,
02278 KEY_ALL_ACCESS,
02279
FALSE
02280 );
02281
02282
if (!
NT_SUCCESS(status)) {
02283
goto cleanup;
02284 }
02285
02286 PiWstrToUnicodeString(&unicodeName,
L"{4D36E972-E325-11CE-BFC1-08002BE10318}\\0000");
02287
02288 status =
IopOpenRegistryKey(¶metersHandle,
02289 tmpHandle,
02290 &unicodeName,
02291 KEY_ALL_ACCESS,
02292
FALSE
02293 );
02294
02295 ZwClose(tmpHandle);
02296
02297
if (!
NT_SUCCESS(status)) {
02298
goto cleanup;
02299 }
02300
02301
02302
02303
02304
02305 keyValueBasic = (PKEY_VALUE_BASIC_INFORMATION)dataBuffer;
02306 enumerateIndex = 0;
02307
02308
while (
TRUE) {
02309
02310 RtlZeroMemory(dataBuffer,
sizeof(dataBuffer));
02311
02312 status = ZwEnumerateValueKey(
02313 parametersHandle,
02314 enumerateIndex,
02315 KeyValueBasicInformation,
02316 keyValueBasic,
02317
sizeof(dataBuffer),
02318 &length
02319 );
02320
if (status == STATUS_NO_MORE_ENTRIES) {
02321 status = STATUS_SUCCESS;
02322
break;
02323 }
02324
02325
if (!
NT_SUCCESS(status)) {
02326
goto cleanup;
02327 }
02328
02329
02330
02331
02332
02333
02334
02335
if (_wcsicmp(keyValueBasic->Name,
L"NetCfgInstanceID") != 0) {
02336
02337
RtlInitUnicodeString(&keyName, keyValueBasic->Name);
02338 status = ZwDeleteValueKey(
02339 parametersHandle,
02340 &keyName
02341 );
02342
02343
if (!
NT_SUCCESS(status)) {
02344
goto cleanup;
02345 }
02346
02347 }
else {
02348
02349 enumerateIndex = 1;
02350 }
02351
02352 }
02353
02354
02355
02356
02357
02358
02359 PiWstrToUnicodeString(&unicodeName,
L"RemoteBootCard");
02360 tmpValue = 1;
02361 ZwSetValueKey(parametersHandle,
02362 &unicodeName,
02363
TITLE_INDEX_VALUE,
02364 REG_DWORD,
02365 &tmpValue,
02366
sizeof(tmpValue)
02367 );
02368
02369
02370
02371
02372
02373
02374 registryList = setupLoaderBlock->
NetbootCardRegistry;
02375
02376
if (registryList !=
NULL) {
02377
02378 STRING aString;
02379 UNICODE_STRING uString, uString2;
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389 uString.Buffer = tempNameBuffer;
02390 uString.MaximumLength =
sizeof(tempNameBuffer);
02391
02392
while (*registryList !=
'\0') {
02393
02394
02395
02396
02397
02398
RtlInitString(&aString, registryList);
02399
RtlAnsiStringToUnicodeString(&uString, &aString,
FALSE);
02400
02401
02402
02403
02404
02405 registryList += (
strlen(registryList) + 1);
02406
02407
if (*registryList ==
'1') {
02408
02409
02410
02411
02412
02413 registryList += 2;
02414 tmpValue = 0;
02415
02416
while (*registryList !=
'\0') {
02417 tmpValue = (tmpValue * 10) + (*registryList -
'0');
02418 ++registryList;
02419 }
02420
02421 ZwSetValueKey(parametersHandle,
02422 &uString,
02423
TITLE_INDEX_VALUE,
02424 REG_DWORD,
02425 &tmpValue,
02426
sizeof(tmpValue)
02427 );
02428
02429 registryList += (
strlen(registryList) + 1);
02430
02431 }
else if (*registryList ==
'2') {
02432
02433
02434
02435
02436
02437 registryList += 2;
02438
02439 uString2.Buffer = tempValueBuffer;
02440 uString2.MaximumLength =
sizeof(tempValueBuffer);
02441
RtlInitAnsiString(&aString, registryList);
02442
RtlAnsiStringToUnicodeString(&uString2, &aString,
FALSE);
02443
02444 ZwSetValueKey(parametersHandle,
02445 &uString,
02446
TITLE_INDEX_VALUE,
02447 REG_SZ,
02448 uString2.Buffer,
02449 uString2.Length +
sizeof(WCHAR)
02450 );
02451
02452 registryList += (
strlen(registryList) + 1);
02453
02454 }
else {
02455
02456
02457
02458
02459
02460
break;
02461
02462 }
02463
02464 }
02465
02466 }
02467
02468
02469
02470
02471
02472 PiWstrToUnicodeString(&unicodeName,
L"NetCardInfo");
02473
02474 ZwSetValueKey(remoteBootHandle,
02475 &unicodeName,
02476
TITLE_INDEX_VALUE,
02477 REG_BINARY,
02478 setupLoaderBlock->
NetbootCardInfo,
02479
sizeof(NET_CARD_INFO)
02480 );
02481
02482
02483
02484
02485
02486
02487
02488
02489 PiWstrToUnicodeString(&unicodeName,
L"HardwareId");
02490
02491 ZwSetValueKey(remoteBootHandle,
02492 &unicodeName,
02493
TITLE_INDEX_VALUE,
02494 REG_SZ,
02495 setupLoaderBlock->
NetbootCardHardwareId,
02496 (wcslen(setupLoaderBlock->
NetbootCardHardwareId) + 1) *
sizeof(WCHAR)
02497 );
02498
02499 PiWstrToUnicodeString(&unicodeName,
L"DriverName");
02500
02501 ZwSetValueKey(remoteBootHandle,
02502 &unicodeName,
02503
TITLE_INDEX_VALUE,
02504 REG_SZ,
02505 setupLoaderBlock->
NetbootCardDriverName,
02506 (wcslen(setupLoaderBlock->
NetbootCardDriverName) + 1) *
sizeof(WCHAR)
02507 );
02508
02509 PiWstrToUnicodeString(&unicodeName,
L"ServiceName");
02510
02511 ZwSetValueKey(remoteBootHandle,
02512 &unicodeName,
02513
TITLE_INDEX_VALUE,
02514 REG_SZ,
02515 setupLoaderBlock->
NetbootCardServiceName,
02516 (wcslen(setupLoaderBlock->
NetbootCardServiceName) + 1) *
sizeof(WCHAR)
02517 );
02518
02519
02520
02521
02522
02523 PiWstrToUnicodeString(&unicodeName,
L"DeviceInstance");
02524
02525 ZwSetValueKey(remoteBootHandle,
02526 &unicodeName,
02527
TITLE_INDEX_VALUE,
02528 REG_SZ,
02529 UnicodeDeviceInstance->Buffer,
02530 UnicodeDeviceInstance->Length +
sizeof(WCHAR)
02531 );
02532
02533
02534
02535
02536
02537
IopRemoteBootCardInitialized =
TRUE;
02538
02539
02540 cleanup:
02541
if (instanceHandle !=
NULL) {
02542 ZwClose(instanceHandle);
02543 }
02544
if (remoteBootHandle !=
NULL) {
02545 ZwClose(remoteBootHandle);
02546 }
02547
if (parametersHandle !=
NULL) {
02548 ZwClose(parametersHandle);
02549 }
02550
if (currentControlSetHandle !=
NULL) {
02551 ZwClose(currentControlSetHandle);
02552 }
02553
02554
return status;
02555
02556 }
02557
02558
#if defined(REMOTE_BOOT)
02559
NTSTATUS
02560 IopInitCsc(
02561 IN PUCHAR CscPath
02562 )
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580 {
02581
NTSTATUS status;
02582 IO_STATUS_BLOCK ioStatusBlock;
02583 SHADOWINFO shadowInfo;
02584 WIN32_FIND_DATAA * find32;
02585
02586 find32 =
ExAllocatePoolWithTag(NonPagedPool,
sizeof(WIN32_FIND_DATAA), 'bRoI');
02587
if (find32 ==
NULL) {
02588
return STATUS_INSUFFICIENT_RESOURCES;
02589 }
02590
02591 RtlZeroMemory( find32,
sizeof(WIN32_FIND_DATAA) );
02592 find32->nFileSizeHigh = 0;
02593 find32->nFileSizeLow = 0xccab348;
02594 find32->dwReserved1 = 0x8000;
02595
ASSERT(
strlen(CscPath) < MAX_PATH);
02596 strcpy( find32->cFileName, CscPath );
02597
02598 RtlZeroMemory( &shadowInfo,
sizeof(shadowInfo) );
02599 shadowInfo.uStatus = 0x0001;
02600 shadowInfo.uOp = 2;
02601 shadowInfo.lpFind32 = (WIN32_FIND_DATAW *)find32;
02602
02603 status = ZwDeviceIoControlFile(
02604 RdrHandle,
02605 NULL,
02606 NULL,
02607 NULL,
02608 &ioStatusBlock,
02609 IOCTL_SWITCHES,
02610 &shadowInfo,
02611 0,
02612 NULL,
02613 0
02614 );
02615
02616
if (
NT_SUCCESS(status) ) {
02617 status = ioStatusBlock.Status;
02618 }
02619
02620
if (
NT_SUCCESS(status) && shadowInfo.uOp ) {
02621
02622
02623
02624
02625
02626 StartCsc = FLUSH_CSC;
02627 IopSetFlushCSC(SET_FLUSH_CSC);
02628 }
02629
02630
ExFreePool(find32);
02631
02632
return status;
02633 }
02634
02635
NTSTATUS
02636 IopResetCsc(
02637 IN PUCHAR CscPath
02638 )
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661 {
02662
NTSTATUS status;
02663 UNICODE_STRING root;
02664 HSHADOW rootHandle;
02665
02666 PUCHAR nameBuffer;
02667 ULONG nameBufferLength;
02668 ULONG length;
02669 HANDLE handle;
02670 UNICODE_STRING string;
02671 OBJECT_ATTRIBUTES objectAttributes;
02672 PKEY_VALUE_PARTIAL_INFORMATION keyValue;
02673
02674 KdPrint((
"IopResetCsc Start\n" ));
02675
02676
#if 0
02677
02678
02679
02680
02681 IO_STATUS_BLOCK ioStatusBlock;
02682 SHADOWINFO shadowInfo;
02683 WIN32_FIND_DATAA sFind32;
02684
02685 memset(&shadowInfo, 0,
sizeof(SHADOWINFO));
02686 memset(&sFind32, 0,
sizeof(sFind32));
02687 sFind32.nFileSizeHigh = 0;
02688 sFind32.nFileSizeLow = 0xccab348;
02689 sFind32.dwReserved1 = 0x8000;
02690
02691
ASSERT(
strlen(CscPath) < MAX_PATH);
02692 strcpy(sFind32.cFileName, CscPath);
02693
02694 shadowInfo.uOp = 9;
02695 shadowInfo.lpFind32 = (WIN32_FIND_DATAW *)&sFind32;
02696
02697 status = ZwDeviceIoControlFile(
02698 RdrHandle,
02699 NULL,
02700 NULL,
02701 NULL,
02702 &ioStatusBlock,
02703 IOCTL_DO_SHADOW_MAINTENANCE,
02704 &shadowInfo,
02705 0,
02706 NULL,
02707 0
02708 );
02709
02710
if (
NT_SUCCESS(status) ) {
02711 status = ioStatusBlock.Status;
02712 }
02713
02714
if ( !
NT_SUCCESS(status) ) {
02715
return status;
02716 }
02717
02718
#endif
02719
02720
RtlInitUnicodeString( &string, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control" );
02721 InitializeObjectAttributes(
02722 &objectAttributes,
02723 &string,
02724 OBJ_CASE_INSENSITIVE,
02725 NULL,
02726 NULL
02727 );
02728
02729 status = ZwOpenKey( &handle, KEY_ALL_ACCESS, &objectAttributes );
02730
if ( !
NT_SUCCESS(status) ) {
02731 KdPrint((
"IopResetCsc: Unable to open Control key: %x\n", status ));
02732
return status;
02733 }
02734
02735
if ( !
ExpInTextModeSetup ) {
02736
RtlInitUnicodeString( &string, L
"RemoteBootRoot" );
02737 }
else {
02738
RtlInitUnicodeString( &string, L
"RemoteBootMachineDirectory" );
02739 }
02740
02741 nameBufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + (128 *
sizeof(WCHAR));
02742 nameBuffer =
ExAllocatePoolWithTag(NonPagedPool, nameBufferLength, 'bRoI');
02743
if (nameBuffer ==
NULL) {
02744 KdPrint((
"IopResetCsc: Unable to allocate nameBuffer\n"));
02745
return STATUS_INSUFFICIENT_RESOURCES;
02746 }
02747
02748 keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)nameBuffer;
02749 RtlZeroMemory(nameBuffer, nameBufferLength);
02750
02751 status = ZwQueryValueKey(
02752 handle,
02753 &string,
02754 KeyValuePartialInformation,
02755 keyValue,
02756 nameBufferLength,
02757 &length);
02758
02759 ZwClose(handle);
02760
02761
if ( !
NT_SUCCESS(status) ) {
02762 KdPrint((
"IopResetCsc: Unable to read RemoteBootRoot value: %x\n", status ));
02763 KdPrint((
"IopResetCsc: returning: %x\n", status ));
02764
ExFreePool(nameBuffer);
02765
return status;
02766 }
02767
RtlInitUnicodeString(&root, (PWSTR)keyValue->Data);
02768 status = IopMarkRoot( &root, &rootHandle );
02769
if (
NT_SUCCESS(status)) {
02770 status = IopWalkDirectoryTree( &root, rootHandle );
02771 }
02772
02773 KdPrint((
"IopResetCsc: returning: %x\n", status ));
02774
02775
ExFreePool(nameBuffer);
02776
return status;
02777 }
02778
02779 PWSTR
02780 IopBreakPath(
02781 IN PWSTR* Path
02782 )
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804 {
02805 PWSTR start = *Path;
02806
02807
02808
while (*start ==
L'\\') {
02809 start++;
02810 }
02811
02812
02813
02814 *Path = start;
02815
while ((**Path !=
L'\\') && (**Path) ) {
02816 (*Path)++;
02817 }
02818
02819
if (**Path) {
02820
02821 **Path =
L'\0';
02822 }
else {
02823 *Path =
NULL;
02824 }
02825
02826
return start;
02827 }
02828
02829
NTSTATUS
02830 IopMarkRoot(
02831 IN PUNICODE_STRING Root,
02832 OUT PHSHADOW RootHandle
02833 )
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854 {
02855
02856
NTSTATUS Status;
02857 PWSTR current, next;
02858 HSHADOW hDir=0;
02859 HSHADOW hShadow;
02860 BOOLEAN first =
TRUE;
02861 BOOLEAN done;
02862
02863 PWIN32_FIND_DATAW sFind32;
02864 SHADOWINFO sSI;
02865
02866 sFind32 =
ExAllocatePoolWithTag(NonPagedPool,
sizeof(WIN32_FIND_DATAW), 'bRoI');
02867
if (sFind32 ==
NULL) {
02868
return STATUS_INSUFFICIENT_RESOURCES;
02869 }
02870
02871
02872
02873
02874
if (Root->Length >= (
MAX_PATH *
sizeof(WCHAR))) {
02875
02876 KdPrint((
"IopMarkRoot: %ws is invalid\n", Root->Buffer));
02877
Status = STATUS_INVALID_PARAMETER;
02878
goto cleanup;
02879 }
02880
02881
02882
02883
02884
02885
02886 next = Root->Buffer + (
sizeof(
L"\\Device\\LanmanRedirector")/
sizeof(WCHAR));;
02887 current = IopBreakPath(&next);
02888
02889 RtlZeroMemory(sFind32,
sizeof(WIN32_FIND_DATAW));
02890 sFind32->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
02891
02892 wcscpy(sFind32->cFileName, L
"\\\\");
02893 wcscat(sFind32->cFileName, current);
02894
02895
02896
if (next) {
02897 *next =
L'\\';
02898 }
else {
02899
Status = STATUS_INVALID_PARAMETER;
02900
goto cleanup;
02901 }
02902 current = IopBreakPath(&next);
02903
02904 wcscat(sFind32->cFileName, L
"\\");
02905 wcscat(sFind32->cFileName, current);
02906
02907
Status = IopGetShadowExW(hDir, sFind32, &sSI);
02908
if (!
NT_SUCCESS(Status)) {
02909 KdPrint((
"IopMarkRoot: IopGetShadowExW (%ws) failed %lx\n", sFind32->cFileName, Status));
02910
goto cleanup;
02911 }
02912
02913
if (!sSI.hShadow) {
02914
02915
02916
02917
Status = IopCreateShadowW( hDir, sFind32, SHADOW_SPARSE, &hShadow );
02918
02919
if (!
NT_SUCCESS(Status)) {
02920 KdPrint((
"IopMarkRoot: IopCreateShadowW (%ws) failed %lx\n", sFind32->cFileName, Status));
02921
goto cleanup;
02922 }
02923 }
else {
02924 hShadow = sSI.hShadow;
02925 }
02926
02927
02928
Status = IopAddHintFromInode(
02929 hDir,
02930 hShadow,
02931 &sSI.ulHintPri,
02932 &sSI.ulHintFlags,
02933 FLAG_CSC_HINT_PIN_SYSTEM);
02934
02935
#if DBG
02936
if (
Status != STATUS_PENDING) {
02937
if (DebugReset) KdPrint((
"IopAddHintFromInode: modified hint flags for %ws\n", next ));
02938 }
02939
#endif
02940
02941
02942
if (next) {
02943 *next =
L'\\';
02944 }
else {
02945
Status = STATUS_INVALID_PARAMETER;
02946
goto cleanup;
02947 }
02948
02949
do {
02950 current = IopBreakPath(&next);
02951
02952 RtlZeroMemory(sFind32,
sizeof(WIN32_FIND_DATAW));
02953 sFind32->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
02954 wcscpy(sFind32->cFileName, current);
02955
02956 hDir = hShadow;
02957
02958
Status = IopGetShadowExW(hDir, sFind32, &sSI);
02959
if (!
NT_SUCCESS(Status)) {
02960 KdPrint((
"IopMarkRoot: IopGetShadowExW (%ws) failed %lx\n", sFind32->cFileName, Status));
02961
goto cleanup;
02962 }
02963
02964
02965
if (!sSI.hShadow) {
02966
02967
02968
02969
Status = IopCreateShadowW( hDir, sFind32, SHADOW_SPARSE, &hShadow );
02970
02971
if (!
NT_SUCCESS(Status)) {
02972 KdPrint((
"IopMarkRoot: IopCreateShadowW (%ws) failed %lx\n", sFind32->cFileName, Status));
02973
goto cleanup;
02974 }
02975
02976 }
else {
02977 hShadow = sSI.hShadow;
02978 }
02979
02980
if (next) {
02981
02982
02983
Status = IopAddHintFromInode(
02984 hDir,
02985 hShadow,
02986 &sSI.ulHintPri,
02987 &sSI.ulHintFlags,
02988 FLAG_CSC_HINT_PIN_SYSTEM);
02989
02990
#if DBG
02991
if (
Status != STATUS_PENDING) {
02992
if (DebugReset) KdPrint((
"IopAddHintFromInode: modified hint flags for %ws\n", next ));
02993 }
02994
#endif
02995
02996
02997 *next =
L'\\';
02998
02999 }
else {
03000
03001
03002
03003
03004
Status = IopAddHintFromInode(
03005 hDir,
03006 hShadow,
03007 &sSI.ulHintPri,
03008 &sSI.ulHintFlags,
03009 (FLAG_CSC_HINT_PIN_SYSTEM | FLAG_CSC_HINT_PIN_INHERIT_SYSTEM));
03010
03011
#if DBG
03012
if (
Status != STATUS_PENDING) {
03013
if (DebugReset) KdPrint((
"IopAddHintFromInode: modified hint flags for %ws\n", next ));
03014 }
03015
#endif
03016
03017 *RootHandle = hShadow;
03018
03019
break;
03020 }
03021
03022 }
while (
TRUE );
03023
03024 cleanup:
03025
03026
ExFreePool(sFind32);
03027
03028
return Status;
03029 }
03030
03031
VOID
03032 IopSetFlushCSC(
03033 IN CSC_CONTROL Command
03034 )
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052 {
03053
03054
NTSTATUS status;
03055 HANDLE handle;
03056 OBJECT_ATTRIBUTES objectAttributes;
03057 UNICODE_STRING string;
03058
DWORD dword = Command;
03059
03060 PKEY_VALUE_PARTIAL_INFORMATION keyValue;
03061 UCHAR buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
sizeof(
DWORD)];
03062 ULONG length;
03063
03064
RtlInitUnicodeString( &string, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control" );
03065
03066 InitializeObjectAttributes(
03067 &objectAttributes,
03068 &string,
03069 OBJ_CASE_INSENSITIVE,
03070 NULL,
03071 NULL
03072 );
03073
03074 status = ZwOpenKey( &handle, KEY_ALL_ACCESS, &objectAttributes );
03075
if ( !
NT_SUCCESS(status) ) {
03076
return;
03077 }
03078
03079
RtlInitUnicodeString( &string, L
"ControlCSC" );
03080
03081
if (Command == READ_CSC) {
03082
03083 keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
03084 status = ZwQueryValueKey(
03085 handle,
03086 &string,
03087 KeyValuePartialInformation,
03088 keyValue,
03089
sizeof(buffer),
03090 &length);
03091
03092 dword = *((
DWORD *)(&keyValue->Data[0]));
03093
03094
if (
NT_SUCCESS(status) && (dword == SET_FLUSH_CSC)) {
03095 StartCsc = FLUSH_CSC;
03096 }
03097
03098 }
else {
03099 status = ZwSetValueKey(
03100 handle,
03101 &string,
03102 0,
03103 REG_DWORD,
03104 &dword,
03105
sizeof(DWORD)
03106 );
03107
if ( !
NT_SUCCESS(status) ) {
03108 KdPrint((
"IopSetFlushCSC: Unable to set ControlCSC value: %x\n", status ));
03109 }
03110 }
03111
03112 ZwClose( handle );
03113
03114
return;
03115 }
03116
03117
NTSTATUS
03118 IopWalkDirectoryHelper(
03119 IN PUNICODE_STRING Directory,
03120 IN HSHADOW CSCHandle,
03121 IN PUCHAR Buffer,
03122 IN ULONG BufferSize
03123 )
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149 {
03150
03151
NTSTATUS Status;
03152
03153 HANDLE FileHandle;
03154 OBJECT_ATTRIBUTES
ObjectAttributes;
03155 IO_STATUS_BLOCK IoStatus;
03156 PUCHAR CopyAclBuffer;
03157
03158
NTSTATUS NtStatus;
03159
03160 PFILE_BOTH_DIR_INFORMATION FileInfo;
03161 ULONG i;
03162 PWIN32_FIND_DATAW sFind32;
03163
03164 PWCHAR SkipNames[] = {
L".",
03165
L"..",
03166
L"pagefile.sys",
03167
L"csc",
03168
L"RECYCLER",
03169
L"TEMP",
03170
L"TMP",
03171
L""};
03172 BOOLEAN skip;
03173
03174
03175 sFind32 =
ExAllocatePoolWithTag(NonPagedPool,
sizeof(WIN32_FIND_DATAW), 'bRoI');
03176
if (sFind32 ==
NULL) {
03177
return STATUS_INSUFFICIENT_RESOURCES;
03178 }
03179
03180 CopyAclBuffer =
ExAllocatePoolWithTag(NonPagedPool, 512, 'bRoI');
03181
if (CopyAclBuffer ==
NULL) {
03182
ExFreePool(sFind32);
03183
return STATUS_INSUFFICIENT_RESOURCES;
03184 }
03185
03186
03187
03188
03189
03190 InitializeObjectAttributes(
03191 &ObjectAttributes,
03192 Directory,
03193 OBJ_CASE_INSENSITIVE,
03194 NULL,
03195 NULL
03196 );
03197
03198
if (!
NT_SUCCESS(Status =
ZwOpenFile( &FileHandle,
03199 FILE_LIST_DIRECTORY | SYNCHRONIZE,
03200 &ObjectAttributes,
03201 &IoStatus,
03202 FILE_SHARE_READ,
03203 FILE_DIRECTORY_FILE ))) {
03204
goto cleanup;
03205 }
03206
03207
03208
03209
03210
03211
for (NtStatus = ZwQueryDirectoryFile( FileHandle,
03212 (HANDLE)NULL,
03213 (PIO_APC_ROUTINE)NULL,
03214 (PVOID)NULL,
03215 &IoStatus,
03216 Buffer,
03217 BufferSize,
03218 FileBothDirectoryInformation,
03219 FALSE,
03220 (PUNICODE_STRING)NULL,
03221 TRUE);
03222
NT_SUCCESS(NtStatus);
03223 NtStatus = ZwQueryDirectoryFile( FileHandle,
03224 (HANDLE)NULL,
03225 (PIO_APC_ROUTINE)NULL,
03226 (PVOID)NULL,
03227 &IoStatus,
03228 Buffer,
03229 BufferSize,
03230 FileBothDirectoryInformation,
03231 FALSE,
03232 (PUNICODE_STRING)NULL,
03233 FALSE) ) {
03234
03235
if (!
NT_SUCCESS(Status = ZwWaitForSingleObject(FileHandle, TRUE, NULL))) {
03236
goto cleanup;
03237 }
03238
03239
03240
03241
03242
03243
if (!
NT_SUCCESS(IoStatus.Status)) {
03244
break;
03245 }
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256 FileInfo = (PFILE_BOTH_DIR_INFORMATION)&
Buffer[0];
03257
03258
while (
TRUE) {
03259
03260 {
03261 WCHAR Saved;
03262
DWORD Index;
03263
03264 Saved = FileInfo->FileName[FileInfo->FileNameLength/2];
03265 FileInfo->FileName[FileInfo->FileNameLength/2] = 0;
03266
03267
Index = 0;
03268 skip =
FALSE;
03269
while (SkipNames[
Index][0] !=
L'\0') {
03270
if (_wcsicmp( FileInfo->FileName,SkipNames[Index])) {
03271
Index++;
03272 }
else {
03273 skip =
TRUE;
03274
break;
03275 }
03276 }
03277
03278
if (!skip) {
03279 UNICODE_STRING Entry;
03280 SHADOWINFO sSI;
03281 PDIRENT pDE;
03282
03283
RtlInitUnicodeString(&Entry,NULL);
03284
03285
if (FileInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
03286
03287
03288
03289
03290 UNICODE_STRING DirName;
03291
USHORT NewNameLength;
03292
03293
RtlInitUnicodeString(&DirName, FileInfo->FileName);
03294
03295 NewNameLength =
03296 (
Directory->Length + DirName.Length + 1) *
sizeof(WCHAR);
03297
03298 pDE =
ExAllocatePoolWithTag(PagedPool,
sizeof(DIRENT) + NewNameLength, 'bRoI');
03299
03300
if (pDE ==
NULL) {
03301 KdPrint((
"Couldn't allocate space for directory\n"));
03302 KdPrint((
"\\%ws\\%ws\n",
Directory->Buffer, FileInfo->FileName));
03303
Status = STATUS_INSUFFICIENT_RESOURCES;
03304
goto cleanup;
03305 }
03306
03307 InsertHeadList( &DirectoryList , &pDE->Next );
03308 pDE->Directory.Length=0;
03309 pDE->Directory.MaximumLength=NewNameLength;
03310 pDE->Directory.Buffer = &pDE->Name[0];
03311
RtlCopyUnicodeString(&pDE->Directory, Directory);
03312
RtlAppendUnicodeToString(&pDE->Directory, L
"\\");
03313 pDE->LastToken = pDE->Directory.Buffer + (pDE->Directory.Length/
sizeof(WCHAR));
03314
RtlAppendUnicodeStringToString(&pDE->Directory, &DirName);
03315 }
03316
03317 RtlZeroMemory(sFind32,
sizeof(WIN32_FIND_DATAW));
03318 wcscpy(sFind32->cFileName, FileInfo->FileName);
03319
03320
Status = IopGetShadowExW(CSCHandle, sFind32, &sSI);
03321
if (!
NT_SUCCESS(Status)) {
03322 KdPrint((
"IopGetShadowExW: returned: %x for %wZ\\%ws\n", Status, Directory, FileInfo->FileName ));
03323
goto cleanup;
03324 }
03325
03326
if (!sSI.hShadow) {
03327
03328 sFind32->dwFileAttributes = FileInfo->FileAttributes;
03329 sFind32->ftCreationTime = *(LPFILETIME)&FileInfo->CreationTime;
03330 sFind32->ftLastAccessTime = *(LPFILETIME)&FileInfo->LastAccessTime;
03331 sFind32->ftLastWriteTime = *(LPFILETIME)&FileInfo->LastWriteTime;
03332 sFind32->nFileSizeLow = FileInfo->EndOfFile.LowPart;
03333 sFind32->nFileSizeHigh = FileInfo->EndOfFile.HighPart;
03334 memcpy(
03335 sFind32->cAlternateFileName,
03336 FileInfo->ShortName,
03337 FileInfo->ShortNameLength );
03338
Status = IopCreateShadowW( CSCHandle, sFind32, SHADOW_SPARSE, &sSI.hShadow);
03339
03340
if (!
NT_SUCCESS(Status)) {
03341 KdPrint((
"IopCreateShadowW: returned: %x for %wZ\\%ws\n", Status, Directory, FileInfo->FileName ));
03342
goto cleanup;
03343 }
03344
03345
Status = IopCopyServerAcl(
03346 FileHandle,
03347 FileInfo->FileName,
03348 sSI.hShadow,
03349 TRUE,
03350 CopyAclBuffer,
03351 512);
03352
#if 0
03353
03354
03355
03356
03357
03358
if (!
NT_SUCCESS(Status)) {
03359
goto cleanup;
03360 }
03361
#endif
03362
}
03363
ASSERT(CSCHandle == sSI.hDir);
03364
03365
Status = IopAddHintFromInode(
03366 sSI.hDir,
03367 sSI.hShadow,
03368 &sSI.ulHintPri,
03369 &sSI.ulHintFlags,
03370 (FLAG_CSC_HINT_PIN_SYSTEM | FLAG_CSC_HINT_PIN_INHERIT_SYSTEM));
03371
03372
#if DBG
03373
if (
Status != STATUS_PENDING) {
03374
if (DebugReset) KdPrint((
"IopAddHintFromInode: modified hint flags for %wZ\\%ws\n", Directory, FileInfo->FileName ));
03375 }
03376
#endif
03377
if (!
NT_SUCCESS(Status)) {
03378 KdPrint((
"IopAddHintFromInode: returned: %x for %wZ\\%ws\n", Status, Directory, FileInfo->FileName ));
03379
goto cleanup;
03380 }
03381
03382
if (FileInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
03383 pDE->CSCHandle = sSI.hShadow;
03384 }
else {
03385
if ((sSI.uStatus & SHADOW_SPARSE) == 0) {
03386
Status = IopSetShadowInfoW(
03387 sSI.hDir,
03388 sSI.hShadow,
03389 SHADOW_SPARSE,
03390 SHADOW_FLAGS_ASSIGN | SHADOW_FLAGS_TRUNCATE_DATA);
03391
#if DBG
03392
if (DebugReset) KdPrint((
"IopSetShadowInfoW: truncated %wZ\\%ws\n", Directory, FileInfo->FileName ));
03393
#endif
03394
if (!
NT_SUCCESS(Status)) {
03395 KdPrint((
"IopSetShadowInfoW: returned: %x for %wZ\\%ws\n", Status, Directory, FileInfo->FileName ));
03396
goto cleanup;
03397 }
03398 }
03399 }
03400 }
03401
03402 FileInfo->FileName[FileInfo->FileNameLength/2] = Saved;
03403 }
03404
03405
03406
03407
03408
03409
03410
03411
if (FileInfo->NextEntryOffset == 0) {
03412
break;
03413 }
03414
03415
03416
03417
03418
03419
03420
03421 FileInfo = (PFILE_BOTH_DIR_INFORMATION)(((PUCHAR)FileInfo) + FileInfo->NextEntryOffset);
03422
03423 }
03424 }
03425
03426 ZwClose( FileHandle );
03427
03428
Status = STATUS_SUCCESS;
03429
03430 cleanup:
03431
03432
ExFreePool(sFind32);
03433
ExFreePool(CopyAclBuffer);
03434
03435
return Status;
03436
03437 }
03438
03439
NTSTATUS
03440 IopWalkDirectoryTree(
03441 IN PUNICODE_STRING Directory,
03442 IN HSHADOW CSCHandle
03443 )
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462 {
03463
03464 PDIRENT Next;
03465
NTSTATUS status;
03466
03467
#define BUFFERSIZE 1024
03468
PUCHAR
Buffer;
03469
03470
03471
03472
Buffer =
ExAllocatePoolWithTag(NonPagedPool, BUFFERSIZE+2, 'bRoI');
03473
03474
if (
Buffer ==
NULL) {
03475
return STATUS_INSUFFICIENT_RESOURCES;
03476 }
03477
03478 InitializeListHead(&DirectoryList);
03479
03480 status = IopWalkDirectoryHelper(Directory, CSCHandle, Buffer, BUFFERSIZE);
03481
03482
if (!
NT_SUCCESS(status)) {
03483
while (!IsListEmpty(&DirectoryList)) {
03484 Next = (PDIRENT)RemoveHeadList(&DirectoryList);
03485
ExFreePool(Next);
03486 }
03487
ExFreePool(Buffer);
03488
return status;
03489 }
03490
03491
03492
03493
03494
03495
03496
while (!IsListEmpty(&DirectoryList)) {
03497
03498 Next = (PDIRENT)RemoveHeadList(&DirectoryList);
03499
03500 status = IopWalkDirectoryHelper(&Next->Directory, Next->CSCHandle, Buffer, BUFFERSIZE);
03501
03502
ExFreePool(Next);
03503
03504
if (!
NT_SUCCESS(status)) {
03505
while (!IsListEmpty(&DirectoryList)) {
03506 Next = (PDIRENT)RemoveHeadList(&DirectoryList);
03507
ExFreePool(Next);
03508 }
03509
03510
ExFreePool(Buffer);
03511
return status;
03512 }
03513 }
03514
03515 IopSetFlushCSC(SET_FLUSHED_CSC);
03516
ExFreePool(Buffer);
03517
return status;
03518
03519 }
03520
03521
03522
03523
03524
NTSTATUS
03525 IopGetShadowExW(
03526 HSHADOW hDir,
03527 LPWIN32_FIND_DATAW lpFind32,
03528 LPSHADOWINFO lpSI
03529 )
03530 {
03531 IO_STATUS_BLOCK Iosb;
03532
NTSTATUS status;
03533
03534 RtlZeroMemory((PUCHAR)lpSI,
sizeof(SHADOWINFO));
03535 lpSI->hDir = hDir;
03536 lpSI->lpFind32 = lpFind32;
03537
03538 status = ZwDeviceIoControlFile(
03539 RdrHandle,
03540 NULL,
03541 NULL,
03542 NULL,
03543 &Iosb,
03544 IOCTL_GETSHADOW,
03545 (LPVOID)(lpSI),
03546 0,
03547 NULL,
03548 0
03549 );
03550
03551
ASSERT( status != STATUS_PENDING );
03552
if (
NT_SUCCESS(status) ) {
03553 status = Iosb.Status;
03554 }
03555
03556
return status;
03557 }
03558
03559
03560
03561
03562
03563
03564
03565
NTSTATUS
03566 IopAddHintFromInode(
03567 HSHADOW hDir,
03568 HSHADOW hShadow,
03569 ULONG *lpulHintPri,
03570 ULONG *lpulHintFlags,
03571 ULONG HintFlagsToSet
03572 )
03573 {
03574
03575 IO_STATUS_BLOCK Iosb;
03576
NTSTATUS status;
03577 SHADOWINFO sSI;
03578
03579 HintFlagsToSet |= FLAG_CSC_HINT_CONSERVE_BANDWIDTH;
03580
03581
if ((*lpulHintFlags & HintFlagsToSet) != HintFlagsToSet) {
03582
03583 RtlZeroMemory(&sSI,
sizeof(SHADOWINFO));
03584 sSI.hDir = hDir;
03585 sSI.hShadow = hShadow;
03586 sSI.ulHintFlags = *lpulHintFlags | HintFlagsToSet;
03587 sSI.uOp = SHADOW_ADDHINT_FROM_INODE;
03588
03589 status = ZwDeviceIoControlFile(
03590 RdrHandle,
03591 NULL,
03592 NULL,
03593 NULL,
03594 &Iosb,
03595 IOCTL_DO_SHADOW_MAINTENANCE,
03596 (LPVOID)(&sSI),
03597 0,
03598 NULL,
03599 0
03600 );
03601
03602
ASSERT( status != STATUS_PENDING );
03603
if (
NT_SUCCESS(status) ) {
03604 status = Iosb.Status;
03605 }
03606
03607
if (
NT_SUCCESS(status)) {
03608 *lpulHintFlags = sSI.ulHintFlags;
03609 *lpulHintPri = sSI.ulHintPri;
03610 }
03611 }
else {
03612 status = STATUS_PENDING;
03613 }
03614
03615
return status;
03616 }
03617
03618
03619
03620
03621
03622
NTSTATUS
03623 IopSetShadowInfoW(
03624 HSHADOW hDir,
03625 HSHADOW hShadow,
03626 ULONG uStatus,
03627 ULONG uOp
03628 )
03629 {
03630
03631 IO_STATUS_BLOCK Iosb;
03632
NTSTATUS status;
03633 SHADOWINFO sSI;
03634
03635 RtlZeroMemory(&sSI,
sizeof(SHADOWINFO));
03636 sSI.hDir = hDir;
03637 sSI.hShadow = hShadow;
03638 sSI.uStatus = uStatus;
03639 sSI.uOp = uOp;
03640
03641 status = ZwDeviceIoControlFile(
03642 RdrHandle,
03643 NULL,
03644 NULL,
03645 NULL,
03646 &Iosb,
03647 IOCTL_SHADOW_SET_SHADOW_INFO,
03648 (LPVOID)(&sSI),
03649 0,
03650 NULL,
03651 0
03652 );
03653
03654
ASSERT( status != STATUS_PENDING );
03655
if (
NT_SUCCESS(status) ) {
03656 status = Iosb.Status;
03657 }
03658
03659
return status;
03660 }
03661
03662
03663
03664
03665
03666
03667
NTSTATUS
03668 IopCreateShadowW(
03669 HSHADOW hDir,
03670 LPWIN32_FIND_DATAW lpFind32,
03671 ULONG uStatus,
03672 PHSHADOW lphShadow
03673 )
03674 {
03675 IO_STATUS_BLOCK Iosb;
03676
NTSTATUS status;
03677 SHADOWINFO sSI;
03678
03679 RtlZeroMemory(&sSI,
sizeof(SHADOWINFO));
03680 sSI.hDir = hDir;
03681 sSI.uStatus = uStatus;
03682 sSI.lpFind32 = lpFind32;
03683
03684
03685 status = ZwDeviceIoControlFile(
03686 RdrHandle,
03687 NULL,
03688 NULL,
03689 NULL,
03690 &Iosb,
03691 IOCTL_SHADOW_CREATE,
03692 (LPVOID)(&sSI),
03693 0,
03694 NULL,
03695 0
03696 );
03697
03698
ASSERT( status != STATUS_PENDING );
03699
if (
NT_SUCCESS(status) ) {
03700 status = Iosb.Status;
03701 }
03702
03703
if (
NT_SUCCESS(status)) {
03704 *lphShadow = sSI.hShadow;
03705 }
03706
03707
return status;
03708 }
03709
03710
NTSTATUS
03711 IopCopyServerAcl(
03712 HANDLE ParentHandle,
03713 PWCHAR FileName,
03714 HSHADOW ShadowHandle,
03715 BOOLEAN IsDirectory,
03716 PUCHAR Buffer,
03717 ULONG BufferSize
03718 )
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748 {
03749 PWCHAR ShadowFileName =
NULL;
03750 UNICODE_STRING ShadowFileString;
03751 UNICODE_STRING FileNameString;
03752 OBJECT_ATTRIBUTES
ObjectAttributes;
03753 IO_STATUS_BLOCK IoStatusBlock;
03754 COPYPARAMSW CopyParams;
03755 HANDLE ShadowFileHandle;
03756 HANDLE ServerFileHandle;
03757 ULONG LengthNeeded;
03758 PSECURITY_DESCRIPTOR SecurityDescriptor;
03759 BOOLEAN AllocatedSecurityDescriptor =
FALSE;
03760 PACL
Dacl;
03761 BOOLEAN DaclPresent, DaclDefaulted;
03762
NTSTATUS Status;
03763
03764
03765
03766
03767
03768
RtlInitUnicodeString(&FileNameString, FileName);
03769
03770 InitializeObjectAttributes(
03771 &ObjectAttributes,
03772 &FileNameString,
03773 OBJ_CASE_INSENSITIVE,
03774 ParentHandle,
03775 NULL);
03776
03777
Status =
ZwOpenFile(
03778 &ServerFileHandle,
03779 READ_CONTROL,
03780 &ObjectAttributes,
03781 &IoStatusBlock,
03782 FILE_SHARE_READ | FILE_SHARE_WRITE,
03783 0);
03784
03785
if (!
NT_SUCCESS(Status) || !
NT_SUCCESS(IoStatusBlock.Status)) {
03786 KdPrint((
"IopCopyServerAcl: ZwOpenFile on %wZ failed %lx %lx\n", &FileNameString, Status, IoStatusBlock.Status));
03787
if (
NT_SUCCESS(Status)) {
03788
Status = IoStatusBlock.Status;
03789 }
03790
goto cleanup;
03791 }
03792
03793
03794
03795
03796
03797
Status = ZwQuerySecurityObject(
03798 ServerFileHandle,
03799 DACL_SECURITY_INFORMATION,
03800 Buffer,
03801 BufferSize,
03802 &LengthNeeded);
03803
03804
if (!
NT_SUCCESS(Status)) {
03805
if (
Status == STATUS_BUFFER_TOO_SMALL) {
03806
03807
03808
03809
03810
03811 SecurityDescriptor =
ExAllocatePoolWithTag(PagedPool, LengthNeeded, 'bRoI');
03812
if (SecurityDescriptor ==
NULL) {
03813
Status = STATUS_INSUFFICIENT_RESOURCES;
03814 }
else {
03815 AllocatedSecurityDescriptor =
TRUE;
03816
03817
Status = ZwQuerySecurityObject(
03818 ServerFileHandle,
03819 DACL_SECURITY_INFORMATION,
03820 SecurityDescriptor,
03821 LengthNeeded,
03822 &LengthNeeded);
03823
03824 }
03825 }
03826
if (!
NT_SUCCESS(Status)) {
03827 KdPrint((
"IopCopyServerAcl: Could not ZwQuerySecurityObject on %wZ %lx\n", &FileNameString, Status));
03828 ZwClose(ServerFileHandle);
03829
goto cleanup;
03830 }
03831
03832 }
else {
03833
03834 SecurityDescriptor = (PSECURITY_DESCRIPTOR)
Buffer;
03835 }
03836
03837 ZwClose(ServerFileHandle);
03838
03839
03840
03841
03842
03843
03844
Status =
RtlGetDaclSecurityDescriptor(
03845 SecurityDescriptor,
03846 &DaclPresent,
03847 &Dacl,
03848 &DaclDefaulted);
03849
03850
if (!
NT_SUCCESS(Status) || !DaclPresent || (
Dacl ==
NULL)) {
03851
03852
goto cleanup;
03853 }
03854
03855
03856
03857
03858
03859 ShadowFileName =
ExAllocatePoolWithTag(NonPagedPool,
sizeof(WCHAR) * MAX_PATH, 'bRoI');
03860
if (ShadowFileName ==
NULL) {
03861 KdPrint((
"IopCopyServerAcl: Could not allocate ShadowFileName\n"));
03862
goto cleanup;
03863 }
03864
03865
Status = IopGetShadowPathW(
03866 ShadowHandle,
03867 ShadowFileName,
03868 &CopyParams);
03869
03870
if (!
NT_SUCCESS(Status)) {
03871 KdPrint((
"IopCopyServerAcl: IopGetShadowPathW failed on %wZ %lx\n", &FileNameString, Status));
03872
goto cleanup;
03873 }
03874
03875
03876
03877
03878
03879
RtlInitUnicodeString(&ShadowFileString, ShadowFileName);
03880
03881 InitializeObjectAttributes(
03882 &ObjectAttributes,
03883 &ShadowFileString,
03884 OBJ_CASE_INSENSITIVE,
03885 NULL,
03886 NULL);
03887
03888
Status =
ZwOpenFile(
03889 &ShadowFileHandle,
03890 WRITE_DAC,
03891 &ObjectAttributes,
03892 &IoStatusBlock,
03893 FILE_SHARE_READ | FILE_SHARE_WRITE,
03894 0);
03895
03896
if (!
NT_SUCCESS(Status) || !
NT_SUCCESS(IoStatusBlock.Status)) {
03897 KdPrint((
"IopCopyServerAcl: ZwOpenFile on %wZ (%wZ) failed %lx %lx\n", &FileNameString, &ShadowFileString, Status, IoStatusBlock.Status));
03898
if (
NT_SUCCESS(Status)) {
03899
Status = IoStatusBlock.Status;
03900 }
03901
goto cleanup;
03902 }
03903
03904
03905
03906
03907
03908
Status = ZwSetSecurityObject(
03909 ShadowFileHandle,
03910 DACL_SECURITY_INFORMATION,
03911 SecurityDescriptor);
03912
03913 ZwClose(ShadowFileHandle);
03914
03915
if (!
NT_SUCCESS(Status)) {
03916 KdPrint((
"IopCopyServerAcl: Could not ZwSetSecurityObject on %wZ %lx\n", &FileNameString, Status));
03917 }
03918
03919 cleanup:
03920
03921
if (AllocatedSecurityDescriptor) {
03922
ExFreePool(SecurityDescriptor);
03923 }
03924
if (ShadowFileName !=
NULL) {
03925
ExFreePool(ShadowFileName);
03926 }
03927
03928
return Status;
03929
03930 }
03931
03932
03933
03934
03935
03936
NTSTATUS
03937 IopGetShadowPathW(
03938 HSHADOW hShadow,
03939 PWCHAR lpLocalPath,
03940 LPCOPYPARAMSW lpCP
03941 )
03942 {
03943 IO_STATUS_BLOCK Iosb;
03944
NTSTATUS status;
03945
03946 RtlZeroMemory((PUCHAR)lpCP,
sizeof(COPYPARAMSW));
03947 lpCP->hShadow = hShadow;
03948 lpCP->lpLocalPath = lpLocalPath;
03949 lpCP->uOp = 1;
03950
03951 status = ZwDeviceIoControlFile(
03952 RdrHandle,
03953 NULL,
03954 NULL,
03955 NULL,
03956 &Iosb,
03957 IOCTL_SHADOW_GET_UNC_PATH,
03958 (LPVOID)(lpCP),
03959 0,
03960 NULL,
03961 0
03962 );
03963
03964
ASSERT( status != STATUS_PENDING );
03965
if (
NT_SUCCESS(status) ) {
03966 status = Iosb.Status;
03967 }
03968
03969
return status;
03970 }
03971
#endif // defined(REMOTE_BOOT)
03972
03973
NTSTATUS
03974 IopWriteIpAddressToRegistry(
03975 HANDLE handle,
03976 PWCHAR regkey,
03977 PUCHAR value
03978 )
03979 {
03980
NTSTATUS status;
03981 UNICODE_STRING string;
03982
CHAR addressA[16];
03983 WCHAR addressW[16];
03984 STRING addressStringA;
03985 UNICODE_STRING addressStringW;
03986
03987
RtlInitUnicodeString( &string, regkey );
03988
03989
sprintf(addressA,
"%d.%d.%d.%d",
03990 value[0],
03991 value[1],
03992 value[2],
03993 value[3]);
03994
03995
RtlInitAnsiString(&addressStringA, addressA);
03996 addressStringW.Buffer = addressW;
03997 addressStringW.MaximumLength =
sizeof(addressW);
03998
03999
RtlAnsiStringToUnicodeString(&addressStringW, &addressStringA,
FALSE);
04000
04001 status =
NtSetValueKey(
04002 handle,
04003 &string,
04004 0,
04005 REG_MULTI_SZ,
04006 addressW,
04007 addressStringW.Length +
sizeof(WCHAR)
04008 );
04009
if ( !
NT_SUCCESS(status) ) {
04010 KdPrint((
"IopWriteIpAddressToRegistry: Unable to set %ws value: %x\n", regkey, status ));
04011 }
04012
return status;
04013 }
04014
04015
04016
NTSTATUS
04017 IopSetDefaultGateway(
04018 IN ULONG GatewayAddress
04019 )
04020
04021
04022
04023
04024
04025
04026
04027
04028
04029
04030
04031
04032
04033
04034
04035 {
04036
NTSTATUS Status;
04037
04038 HANDLE
Handle =
NULL;
04039
BYTE Context[CONTEXT_SIZE];
04040 TDIObjectID
ID;
04041
DWORD Size;
04042 IPSNMPInfo IPStats;
04043 IPAddrEntry *AddrTable =
NULL;
04044
DWORD NumReturned;
04045
DWORD Type;
04046
DWORD i;
04047
DWORD MatchIndex;
04048 IPRouteEntry RouteEntry;
04049 OBJECT_ATTRIBUTES objectAttributes;
04050 UNICODE_STRING NameString;
04051 IO_STATUS_BLOCK ioStatusBlock;
04052
04053
if (GatewayAddress == 0) {
04054
return STATUS_SUCCESS;
04055 }
04056
04057
RtlInitUnicodeString( &NameString, DD_TCP_DEVICE_NAME );
04058
04059 InitializeObjectAttributes(
04060 &objectAttributes,
04061 &NameString,
04062 OBJ_CASE_INSENSITIVE,
04063
NULL,
04064
NULL
04065 );
04066
04067
Status =
NtCreateFile(
04068 &
Handle,
04069 GENERIC_READ | GENERIC_WRITE,
04070 &objectAttributes,
04071 &ioStatusBlock,
04072
NULL,
04073 0,
04074 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
04075 FILE_OPEN,
04076 FILE_SYNCHRONOUS_IO_NONALERT,
04077
NULL,
04078 0
04079 );
04080
if ( !
NT_SUCCESS(
Status) ) {
04081 KdPrint((
"IopSetDefaultGateway: Unable to open TCPIP: %x\n",
Status ));
04082
return Status;
04083 }
04084
04085
04086
04087
04088
04089
ID.toi_entity.tei_entity = CL_NL_ENTITY;
04090
ID.toi_entity.tei_instance = 0;
04091
ID.toi_class = INFO_CLASS_PROTOCOL;
04092
ID.toi_type = INFO_TYPE_PROVIDER;
04093
ID.toi_id = IP_MIB_STATS_ID;
04094
04095
Size =
sizeof(IPStats);
04096 memset(&IPStats, 0x0,
Size);
04097 memset(Context, 0x0, CONTEXT_SIZE);
04098
04099
Status =
IopTCPQueryInformationEx(
04100
Handle,
04101 &
ID,
04102 &IPStats,
04103 &
Size,
04104 Context);
04105
04106
if (!
NT_SUCCESS(
Status)) {
04107 KdPrint((
"IopSetDefaultGateway: Unable to query TCPIP(1): %x\n",
Status ));
04108
goto Cleanup;
04109 }
04110
04111
Size = IPStats.ipsi_numaddr *
sizeof(IPAddrEntry);
04112 AddrTable =
ExAllocatePoolWithTag(
PagedPool,
Size, 'bRoI');
04113
04114
if (AddrTable ==
NULL) {
04115
Status = STATUS_NO_MEMORY;
04116
goto Cleanup;
04117 }
04118
04119
ID.toi_id = IP_MIB_ADDRTABLE_ENTRY_ID;
04120 memset(Context, 0x0, CONTEXT_SIZE);
04121
04122
Status =
IopTCPQueryInformationEx(
04123
Handle,
04124 &
ID,
04125 AddrTable,
04126 &
Size,
04127 Context);
04128
04129
if (!
NT_SUCCESS(
Status)) {
04130 KdPrint((
"IopSetDefaultGateway: Unable to query TCPIP(2): %x\n",
Status ));
04131
goto Cleanup;
04132 }
04133
04134 NumReturned =
Size/
sizeof(IPAddrEntry);
04135
04136
04137
04138
04139
04140
04141
04142
04143 Type = IRE_TYPE_INDIRECT;
04144
for (i = 0, MatchIndex = 0xffff; i < NumReturned; i++) {
04145
04146
if( AddrTable[i].iae_addr == GatewayAddress ) {
04147
04148
04149
04150
04151
04152 MatchIndex = i;
04153 Type = IRE_TYPE_DIRECT;
04154
break;
04155 }
04156
04157
04158
04159
04160
04161
04162
if ( (MatchIndex == 0xffff) &&
04163 (AddrTable[i].iae_addr != 0) &&
04164 (AddrTable[i].iae_mask != 0) &&
04165 ((AddrTable[i].iae_addr & AddrTable[i].iae_mask) ==
04166 (GatewayAddress & AddrTable[i].iae_mask)) ) {
04167
04168 MatchIndex = i;
04169 }
04170 }
04171
04172
04173
04174
04175
04176
if (MatchIndex == 0xffff) {
04177
04178
04179
04180
04181
Status = STATUS_UNSUCCESSFUL;
04182 KdPrint((
"IopSetDefaultGateway: Unable to find match for gateway\n" ));
04183
goto Cleanup;
04184 }
04185
04186
04187
04188
04189
04190
04191 RouteEntry.ire_dest =
DEFAULT_DEST;
04192 RouteEntry.ire_index = AddrTable[MatchIndex].iae_index;
04193 RouteEntry.ire_metric1 =
DEFAULT_METRIC;
04194 RouteEntry.ire_metric2 = (
DWORD)(-1);
04195 RouteEntry.ire_metric3 = (
DWORD)(-1);
04196 RouteEntry.ire_metric4 = (
DWORD)(-1);
04197 RouteEntry.ire_nexthop = GatewayAddress;
04198 RouteEntry.ire_type = Type;
04199 RouteEntry.ire_proto = IRE_PROTO_LOCAL;
04200 RouteEntry.ire_age = 0;
04201 RouteEntry.ire_mask =
DEFAULT_DEST_MASK;
04202 RouteEntry.ire_metric5 = (
DWORD)(-1);
04203 RouteEntry.ire_context =
NULL;
04204
04205
Size =
sizeof(RouteEntry);
04206
04207
ID.toi_id = IP_MIB_RTTABLE_ENTRY_ID;
04208
04209
Status =
IopTCPSetInformationEx(
04210
Handle,
04211 &
ID,
04212 &RouteEntry,
04213
Size );
04214
04215
if (!
NT_SUCCESS(
Status)) {
04216 KdPrint((
"IopSetDefaultGateway: Unable to set default gateway: %x\n",
Status ));
04217 }
04218
04219
NtClose(
Handle);
04220
04221
Handle =
NULL;
04222
04223 Cleanup:
04224
04225
if (
Handle !=
NULL) {
04226
NtClose(
Handle);
04227 }
04228
04229
if( AddrTable !=
NULL ) {
04230
ExFreePool( AddrTable );
04231 }
04232
04233
return Status;
04234 }
04235
04236
04237 __inline
long
04238 htonl(
long x)
04239 {
04240
return((((x) >> 24) & 0x000000FF
L) |
04241 (((x) >> 8) & 0x0000FF00
L) |
04242 (((x) << 8) & 0x00FF0000
L) |
04243 (((x) << 24) & 0xFF000000
L));
04244 }
04245
04246
NTSTATUS
04247 IopCacheNetbiosNameForIpAddress(
04248 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
04249 )
04250
04251
04252
04253
04254
04255
04256
04257
04258
04259
04260
04261
04262
04263
04264
04265 {
04266
NTSTATUS Status;
04267 HANDLE
Handle =
NULL;
04268
BYTE Context[CONTEXT_SIZE];
04269
DWORD Size;
04270 OBJECT_ATTRIBUTES objectAttributes;
04271 UNICODE_STRING NameString;
04272 IO_STATUS_BLOCK ioStatusBlock;
04273 tREMOTE_CACHE cacheInfo;
04274 PCHAR serverName;
04275 PCHAR endOfServerName;
04276
04277
04278
04279
04280
04281
RtlInitUnicodeString(
04282 &NameString,
04283
L"\\Device\\NetBT_Tcpip_{54C7D140-09EF-11D1-B25A-F5FE627ED95E}"
04284 );
04285
04286 InitializeObjectAttributes(
04287 &objectAttributes,
04288 &NameString,
04289 OBJ_CASE_INSENSITIVE,
04290
NULL,
04291
NULL
04292 );
04293
04294
Status =
NtCreateFile(
04295 &
Handle,
04296 GENERIC_READ | GENERIC_WRITE,
04297 &objectAttributes,
04298 &ioStatusBlock,
04299
NULL,
04300 0,
04301 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
04302 FILE_OPEN,
04303 FILE_SYNCHRONOUS_IO_NONALERT,
04304
NULL,
04305 0
04306 );
04307
if ( !
NT_SUCCESS(
Status) ) {
04308 KdPrint((
"IopCacheNetbiosNameForIpAddress: Unable to open NETBT: %x\n",
Status ));
04309
return Status;
04310 }
04311
04312
04313
04314
04315
04316
04317
04318
04319
04320
04321
04322
04323
04324 serverName = LoaderBlock->NtBootPathName;
04325
if ( *serverName ==
'\\' ) {
04326 serverName++;
04327 }
04328 endOfServerName = strchr( serverName,
'\\' );
04329
if ( endOfServerName ==
NULL ) {
04330 endOfServerName = strchr( serverName,
'\0' );
04331 }
04332
04333
04334
04335
04336
04337 memset(&cacheInfo, 0x0,
sizeof(cacheInfo));
04338
04339 memset(cacheInfo.name,
' ', NETBIOS_NAMESIZE);
04340 memcpy(cacheInfo.name, serverName, (ULONG)(endOfServerName - serverName));
04341 cacheInfo.IpAddress =
htonl(LoaderBlock->SetupLoaderBlock->ServerIpAddress);
04342 cacheInfo.Ttl = MAXULONG;
04343
04344
04345
04346
04347
04348
Status =
NtDeviceIoControlFile(
04349
Handle,
04350
NULL,
04351
NULL,
04352
NULL,
04353 &ioStatusBlock,
04354 IOCTL_NETBT_ADD_TO_REMOTE_TABLE,
04355 &cacheInfo,
04356
sizeof(cacheInfo),
04357 Context,
04358
sizeof(Context)
04359 );
04360
04361
ASSERT(
Status != STATUS_PENDING );
04362
if (
NT_SUCCESS(
Status) ) {
04363
Status = ioStatusBlock.Status;
04364 }
04365
04366
if ( !
NT_SUCCESS(
Status) ) {
04367 KdPrint((
"IopCacheNetbiosNameForIpAddress: Adapter status failed: %x\n",
Status ));
04368 }
04369
04370
NtClose(
Handle);
04371
04372
return Status;
04373 }
04374
04375
04376
NTSTATUS
04377 IopTCPQueryInformationEx(
04378 IN HANDLE TCPHandle,
04379 IN TDIObjectID FAR *ID,
04380 OUT
void FAR *Buffer,
04381 IN OUT DWORD FAR *BufferSize,
04382 IN OUT BYTE FAR *Context
04383 )
04384
04385
04386
04387
04388
04389
04390
04391
04392
04393
04394
04395
04396
04397
04398
04399
04400
04401
04402
04403
04404
04405
04406
04407
04408
04409 {
04410 TCP_REQUEST_QUERY_INFORMATION_EX queryBuffer;
04411
DWORD queryBufferSize;
04412
NTSTATUS status;
04413 IO_STATUS_BLOCK ioStatusBlock;
04414
04415
04416
if (TCPHandle ==
NULL) {
04417
return(STATUS_INVALID_PARAMETER);
04418 }
04419
04420 queryBufferSize =
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
04421 memcpy(&(queryBuffer.ID),
ID,
sizeof(TDIObjectID));
04422 memcpy(&(queryBuffer.Context), Context, CONTEXT_SIZE);
04423
04424 status =
NtDeviceIoControlFile(
04425 TCPHandle,
04426
NULL,
04427
NULL,
04428
NULL,
04429 &ioStatusBlock,
04430 IOCTL_TCP_QUERY_INFORMATION_EX,
04431 &queryBuffer,
04432 queryBufferSize,
04433
Buffer,
04434 *
BufferSize
04435 );
04436
04437
ASSERT( status != STATUS_PENDING );
04438
if (
NT_SUCCESS(status) ) {
04439 status = ioStatusBlock.Status;
04440 }
04441
04442
if (status == STATUS_SUCCESS) {
04443
04444
04445
04446 memcpy(Context, &(queryBuffer.Context), CONTEXT_SIZE);
04447 *
BufferSize = (ULONG)ioStatusBlock.Information;
04448 status = ioStatusBlock.Status;
04449 }
else {
04450 *
BufferSize = 0;
04451 }
04452
04453
return(status);
04454 }
04455
04456
04457
NTSTATUS
04458 IopTCPSetInformationEx(
04459 IN HANDLE TCPHandle,
04460 IN TDIObjectID FAR *ID,
04461 IN
void FAR *Buffer,
04462 IN DWORD FAR BufferSize
04463 )
04464
04465
04466
04467
04468
04469
04470
04471
04472
04473
04474
04475
04476
04477
04478
04479
04480
04481
04482
04483
04484
04485 {
04486 PTCP_REQUEST_SET_INFORMATION_EX setBuffer;
04487
NTSTATUS status;
04488 IO_STATUS_BLOCK ioStatusBlock;
04489
DWORD setBufferSize;
04490
04491
04492
if (TCPHandle ==
NULL) {
04493
return(STATUS_INVALID_PARAMETER);
04494 }
04495
04496 setBufferSize = FIELD_OFFSET(TCP_REQUEST_SET_INFORMATION_EX,
Buffer) +
BufferSize;
04497
04498 setBuffer =
ExAllocatePoolWithTag(
PagedPool, setBufferSize, 'bRoI');
04499
04500
if (setBuffer ==
NULL) {
04501
return(STATUS_INSUFFICIENT_RESOURCES);
04502 }
04503
04504 setBuffer->BufferSize =
BufferSize;
04505
04506 memcpy(&(setBuffer->ID),
ID,
sizeof(TDIObjectID));
04507
04508 memcpy(&(setBuffer->Buffer[0]),
Buffer,
BufferSize);
04509
04510 status =
NtDeviceIoControlFile(
04511 TCPHandle,
04512
NULL,
04513
NULL,
04514
NULL,
04515 &ioStatusBlock,
04516 IOCTL_TCP_SET_INFORMATION_EX,
04517 setBuffer,
04518 setBufferSize,
04519
NULL,
04520 0
04521 );
04522
04523
ASSERT( status != STATUS_PENDING );
04524
if (
NT_SUCCESS(status) ) {
04525 status = ioStatusBlock.Status;
04526 }
04527
04528
ExFreePool(setBuffer);
04529
04530
return(status);
04531 }
04532
04533
#if defined(REMOTE_BOOT)
04534
VOID
04535 IopGetHarddiskInfo(
04536 OUT PWSTR NetHDCSCPartition
04537 )
04538
04539
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557
04558 {
04559 PARTITION_INFORMATION PartitionInfo;
04560 FILE_FS_SIZE_INFORMATION SizeInfo;
04561 PWSTR NameBuffer;
04562 PWSTR DiskNameBuffer;
04563 PWSTR NetHDBootPartition;
04564 ULONG DiskNumber;
04565 ULONG PartitionNumber;
04566 ULONG DestPartitionNumber;
04567 HANDLE
Handle;
04568
NTSTATUS Status;
04569 IO_STATUS_BLOCK IoStatus;
04570 OBJECT_ATTRIBUTES
ObjectAttributes;
04571 UNICODE_STRING UnicodeString;
04572 LARGE_INTEGER LargestFreeSpace;
04573 LARGE_INTEGER FreeSpace;
04574
04575 wcscpy(NetHDCSCPartition, L
"\\Device\\Harddisk0\\Partition1");
04576
04577 NameBuffer =
ExAllocatePoolWithTag(NonPagedPool, 80 * 3 *
sizeof(WCHAR), 'bRoI');
04578
if ( NameBuffer ==
NULL ) {
04579 KdPrint((
"IopGetHarddiskInfo: unable to allocate buffer\n" ));
04580
return;
04581 }
04582
04583 DiskNameBuffer = NameBuffer + 80;
04584 NetHDBootPartition = DiskNameBuffer + 80;
04585
04586 wcscpy(DiskNameBuffer, L
"\\Device\\Harddisk0");
04587 wcscpy(NetHDBootPartition, DiskNameBuffer);
04588 wcscpy(NetHDBootPartition, L
"\\Partition1");
04589 wcscpy(NetHDCSCPartition, NetHDBootPartition);
04590
04591
04592
04593
04594
04595 DiskNumber = 0;
04596
while (
TRUE) {
04597
04598
04599
04600
04601 PartitionNumber = 0;
04602
04603 swprintf(NameBuffer, L
"\\Device\\Harddisk%d\\Partition%d", DiskNumber, PartitionNumber);
04604
04605
RtlInitUnicodeString(&UnicodeString, NameBuffer);
04606
04607 InitializeObjectAttributes(
04608 &ObjectAttributes,
04609 &UnicodeString,
04610 OBJ_CASE_INSENSITIVE,
04611 NULL,
04612 NULL
04613 );
04614
04615
Status =
ZwCreateFile( &Handle,
04616 (ACCESS_MASK)FILE_GENERIC_READ,
04617 &ObjectAttributes,
04618 &IoStatus,
04619 NULL,
04620 FILE_ATTRIBUTE_NORMAL,
04621 FILE_SHARE_READ,
04622 FILE_OPEN,
04623 FILE_SYNCHRONOUS_IO_NONALERT,
04624 NULL,
04625 0
04626 );
04627
04628
if (!
NT_SUCCESS(Status)) {
04629
ExFreePool(NameBuffer);
04630
return;
04631 }
04632
04633 ZwClose(Handle);
04634
04635
04636
04637
04638
while (
TRUE) {
04639
04640 PartitionNumber++;
04641
04642 swprintf(NameBuffer, L
"\\Device\\Harddisk%d\\Partition%d", DiskNumber, PartitionNumber);
04643
04644
RtlInitUnicodeString(&UnicodeString, NameBuffer);
04645
04646 InitializeObjectAttributes(
04647 &ObjectAttributes,
04648 &UnicodeString,
04649 OBJ_CASE_INSENSITIVE,
04650 NULL,
04651 NULL
04652 );
04653
04654
04655
Status =
ZwCreateFile( &Handle,
04656 (ACCESS_MASK)FILE_GENERIC_READ,
04657 &ObjectAttributes,
04658 &IoStatus,
04659 NULL,
04660 FILE_ATTRIBUTE_NORMAL,
04661 FILE_SHARE_READ,
04662 FILE_OPEN,
04663 FILE_SYNCHRONOUS_IO_NONALERT,
04664 NULL,
04665 0
04666 );
04667
04668
if (!
NT_SUCCESS(Status)) {
04669
break;
04670 }
04671
04672
Status = ZwDeviceIoControlFile(Handle,
04673 NULL,
04674 NULL,
04675 NULL,
04676 &IoStatus,
04677 IOCTL_DISK_GET_PARTITION_INFO,
04678 NULL,
04679 0,
04680 &PartitionInfo,
04681
sizeof(PARTITION_INFORMATION)
04682 );
04683
04684 ZwClose(Handle);
04685
04686
if (!
NT_SUCCESS(Status)) {
04687
break;
04688 }
04689
04690
if (PartitionInfo.BootIndicator) {
04691 wcscpy(NetHDBootPartition, NameBuffer);
04692 swprintf(DiskNameBuffer, L
"\\Device\\Harddisk%d", DiskNumber);
04693
goto FoundDisk;
04694 }
04695
04696 }
04697
04698 DiskNumber++;
04699 }
04700
04701
ASSERT(0);
04702
04703 FoundDisk:
04704
04705
04706
04707
04708
04709
04710 wcscpy(NetHDCSCPartition, NetHDBootPartition);
04711
04712 PartitionNumber = 0;
04713 DestPartitionNumber = 0;
04714 LargestFreeSpace = RtlConvertUlongToLargeInteger(0);
04715
04716
while (
TRUE) {
04717
04718 PartitionNumber++;
04719
04720
04721
04722
04723 swprintf(NameBuffer,
04724 L
"%ws\\Partition%d%ws",
04725 DiskNameBuffer,
04726 PartitionNumber,
04727 REMOTE_BOOT_IMIRROR_PATH_W REMOTE_BOOT_CSC_SUBDIR_W);
04728
04729
RtlInitUnicodeString(&UnicodeString, NameBuffer);
04730
04731 InitializeObjectAttributes(
04732 &ObjectAttributes,
04733 &UnicodeString,
04734 OBJ_CASE_INSENSITIVE,
04735 NULL,
04736 NULL
04737 );
04738
04739
04740
Status =
ZwOpenFile( &Handle,
04741 FILE_GENERIC_READ,
04742 &ObjectAttributes,
04743 &IoStatus,
04744 FILE_SHARE_READ,
04745 FILE_DIRECTORY_FILE
04746 );
04747
04748
if (
NT_SUCCESS(Status)) {
04749 ZwClose(Handle);
04750 DestPartitionNumber = PartitionNumber;
04751
break;
04752 }
04753
04754
if (
Status == STATUS_UNRECOGNIZED_VOLUME) {
04755
04756
04757
04758
continue;
04759 }
04760
04761
04762
04763
04764 swprintf(NameBuffer, L
"%ws\\Partition%d", DiskNameBuffer, PartitionNumber);
04765
04766
RtlInitUnicodeString(&UnicodeString, NameBuffer);
04767
04768 InitializeObjectAttributes(
04769 &ObjectAttributes,
04770 &UnicodeString,
04771 OBJ_CASE_INSENSITIVE,
04772 NULL,
04773 NULL
04774 );
04775
04776
Status =
ZwCreateFile( &Handle,
04777 FILE_GENERIC_READ,
04778 &ObjectAttributes,
04779 &IoStatus,
04780 NULL,
04781 FILE_ATTRIBUTE_NORMAL,
04782 FILE_SHARE_READ,
04783 FILE_OPEN,
04784 FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_FREE_SPACE_QUERY,
04785 NULL,
04786 0
04787 );
04788
04789
if (!
NT_SUCCESS(Status)) {
04790
break;
04791 }
04792
04793
Status = ZwDeviceIoControlFile(Handle,
04794 NULL,
04795 NULL,
04796 NULL,
04797 &IoStatus,
04798 IOCTL_DISK_GET_PARTITION_INFO,
04799 NULL,
04800 0,
04801 &PartitionInfo,
04802
sizeof(PARTITION_INFORMATION)
04803 );
04804
04805
if (!
NT_SUCCESS(Status) || (PartitionInfo.PartitionType != PARTITION_IFS)) {
04806 ZwClose(Handle);
04807
continue;
04808 }
04809
04810
04811
Status = ZwQueryVolumeInformationFile(
04812 Handle,
04813 &IoStatus,
04814 &SizeInfo,
04815
sizeof(SizeInfo),
04816 FileFsSizeInformation
04817 );
04818
04819 ZwClose(Handle);
04820
04821
if(
NT_SUCCESS(Status)) {
04822
04823
04824
04825
04826 FreeSpace =
RtlExtendedIntegerMultiply(
04827 SizeInfo.AvailableAllocationUnits,
04828 SizeInfo.SectorsPerAllocationUnit * SizeInfo.BytesPerSector
04829 );
04830
04831
if (RtlLargeIntegerGreaterThan(FreeSpace, LargestFreeSpace)) {
04832 LargestFreeSpace = FreeSpace;
04833 DestPartitionNumber = PartitionNumber;
04834 }
04835
04836 }
04837
04838 }
04839
04840
if (DestPartitionNumber != 0) {
04841 swprintf(NetHDCSCPartition, L
"%ws\\Partition%d", DiskNameBuffer, DestPartitionNumber);
04842 }
04843
04844
ExFreePool(NameBuffer);
04845
04846
return;
04847 }
04848
04849
VOID
04850 IoStartCscForTextmodeSetup (
04851 IN BOOLEAN Upgrade
04852 )
04853 {
04854
NTSTATUS status;
04855 PWSTR NetHDCSCPartition;
04856 PUCHAR buffer;
04857 IO_STATUS_BLOCK ioStatusBlock;
04858
04859
if (RdrHandle ==
NULL) {
04860
ASSERT(FALSE);
04861
return;
04862 }
04863
if (!
ExpInTextModeSetup) {
04864
ASSERT(FALSE);
04865
return;
04866 }
04867
if (TextmodeSetupHasStartedCsc) {
04868
ASSERT(FALSE);
04869
return;
04870 }
04871
04872 NetHDCSCPartition =
ExAllocatePoolWithTag(
04873 NonPagedPool,
04874 (80 + MAX_PATH) *
sizeof(WCHAR),
04875 'bRoI'
04876 );
04877
if (NetHDCSCPartition ==
NULL) {
04878 KdPrint((
"IoStartCscForTextmodeSetup: Unable to allocate buffer\n"));
04879
return;
04880 }
04881 buffer = (PUCHAR)(NetHDCSCPartition + 80);
04882
04883
04884
04885
04886
04887
04888 IopGetHarddiskInfo(NetHDCSCPartition);
04889
04890
04891
04892
04893
04894
04895
KeAttachProcess( RdrHandleProcess );
04896
04897 status = ZwFsControlFile(
04898 RdrHandle,
04899 NULL,
04900 NULL,
04901 NULL,
04902 &ioStatusBlock,
04903 FSCTL_LMR_START_RBR,
04904 NetHDCSCPartition,
04905 wcslen(NetHDCSCPartition) *
sizeof(WCHAR),
04906 NULL,
04907 0
04908 );
04909
04910
if (
NT_SUCCESS(status) ) {
04911 status = ioStatusBlock.Status;
04912 }
04913
04914
if ( !
NT_SUCCESS(status) ) {
04915 KdPrint((
"IoStartCscForTextmodeSetup: Unable to FSCTL(RBR) redirector: %x\n", status ));
04916 }
04917
04918 wcstombs(buffer, NetHDCSCPartition, wcslen(NetHDCSCPartition) + 1);
04919 strcat(buffer, REMOTE_BOOT_IMIRROR_PATH_A REMOTE_BOOT_CSC_SUBDIR_A);
04920
04921 StartCsc = INIT_CSC;
04922 status = IopInitCsc( buffer );
04923
04924
04925
04926
04927
04928
04929
if (
NT_SUCCESS(status) && (!Upgrade || (StartCsc == FLUSH_CSC)) ) {
04930
04931 status = IopResetCsc( buffer );
04932
04933
if ( !
NT_SUCCESS(status) ) {
04934 KdPrint((
"IoStartCscForTextmodeSetup: reset of Csc failed %x\n", status));
04935 }
04936 }
04937
04938
if ( !
NT_SUCCESS(status) ) {
04939 KdPrint((
"IoStartCscForTextmodeSetup: initialization of Csc failed %x\n", status));
04940 IoCscInitializationFailed =
TRUE;
04941 SharedUserData->SystemFlags |= SYSTEM_FLAG_DISKLESS_CLIENT;
04942 }
else {
04943 IoCscInitializationFailed =
FALSE;
04944 SharedUserData->SystemFlags &= ~SYSTEM_FLAG_DISKLESS_CLIENT;
04945 }
04946
04947
KeDetachProcess();
04948
04949
ExFreePool( NetHDCSCPartition );
04950
04951
return;
04952
04953 }
04954
#endif // defined(REMOTE_BOOT)
04955