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

netboot.c File Reference

#include "iop.h"
#include <ntddip.h>
#include <nbtioctl.h>
#include <ntddnfs.h>
#include <ntddbrow.h>
#include <ntddtcp.h>
#include <setupblk.h>
#include <remboot.h>
#include <oscpkt.h>
#include <windef.h>
#include <tdiinfo.h>
#include <ipinfo.h>

Go to the source code of this file.

Defines

#define DEFAULT_DEST   0
#define DEFAULT_DEST_MASK   0
#define DEFAULT_METRIC   1

Functions

NTSTATUS IopWriteIpAddressToRegistry (HANDLE handle, PWCHAR regkey, PUCHAR value)
NTSTATUS IopTCPQueryInformationEx (IN HANDLE TCPHandle, IN TDIObjectID FAR *ID, OUT void FAR *Buffer, IN OUT DWORD FAR *BufferSize, IN OUT BYTE FAR *Context)
NTSTATUS IopTCPSetInformationEx (IN HANDLE TCPHandle, IN TDIObjectID FAR *ID, IN void FAR *Buffer, IN DWORD FAR BufferSize)
NTSTATUS IopSetDefaultGateway (IN ULONG GatewayAddress)
NTSTATUS IopCacheNetbiosNameForIpAddress (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID IopAssignNetworkDriveLetter (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
NTSTATUS IopAddRemoteBootValuesToRegistry (PLOADER_PARAMETER_BLOCK LoaderBlock)
NTSTATUS IopStartNetworkForRemoteBoot (PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID IopAssignNetworkDriveLetter (PLOADER_PARAMETER_BLOCK LoaderBlock)
NTSTATUS IopStartTcpIpForRemoteBoot (PLOADER_PARAMETER_BLOCK LoaderBlock)
BOOLEAN IopIsRemoteBootCard (IN PDEVICE_NODE DeviceNode, IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PWCHAR HwIds)
NTSTATUS IopSetupRemoteBootCard (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN HANDLE UniqueIdHandle, IN PUNICODE_STRING UnicodeDeviceInstance)
__inline long htonl (long x)

Variables

BOOLEAN ExpInTextModeSetup


Define Documentation

#define DEFAULT_DEST   0
 

Definition at line 59 of file netboot.c.

Referenced by IopSetDefaultGateway().

#define DEFAULT_DEST_MASK   0
 

Definition at line 60 of file netboot.c.

Referenced by IopSetDefaultGateway().

#define DEFAULT_METRIC   1
 

Definition at line 61 of file netboot.c.

Referenced by IopSetDefaultGateway().


Function Documentation

__inline long htonl long  x  ) 
 

Definition at line 4238 of file netboot.c.

References L.

Referenced by IopCacheNetbiosNameForIpAddress().

04239 { 04240 return((((x) >> 24) & 0x000000FFL) | 04241 (((x) >> 8) & 0x0000FF00L) | 04242 (((x) << 8) & 0x00FF0000L) | 04243 (((x) << 24) & 0xFF000000L)); 04244 }

NTSTATUS IopAddRemoteBootValuesToRegistry PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 314 of file netboot.c.

References _LOADER_PARAMETER_BLOCK::ArcBootDeviceName, ASSERT, CHAR, CmRegistryMachineSystemCurrentControlSetServices, _SETUP_LOADER_BLOCK::ComputerName, _SETUP_LOADER_BLOCK::DefaultRouter, DWORD, FALSE, _SETUP_LOADER_BLOCK::Flags, IopOpenRegistryKey(), IopWriteIpAddressToRegistry(), _SETUP_LOADER_BLOCK::IpAddress, L, _SETUP_LOADER_BLOCK::MachineDirectoryPath, _SETUP_LOADER_BLOCK::NetbootCardDriverName, _SETUP_LOADER_BLOCK::NetbootCardServiceName, NT_SUCCESS, _LOADER_PARAMETER_BLOCK::NtBootPathName, NtClose(), NtDeleteValueKey(), NtOpenKey(), NtQueryValueKey(), NtSetValueKey(), NTSTATUS(), NULL, RtlAnsiStringToUnicodeString(), RtlDnsHostNameToComputerName(), RtlFreeUnicodeString(), RtlInitAnsiString(), RtlInitUnicodeString(), SETUPBLK_FLAGS_IS_TEXTMODE, _LOADER_PARAMETER_BLOCK::SetupLoaderBlock, _SETUP_LOADER_BLOCK::SubnetMask, TITLE_INDEX_VALUE, and TRUE.

Referenced by IoInitSystem().

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 // Convert the name to a Netbios name. 00342 // 00343 00344 _wcsupr( LoaderBlock->SetupLoaderBlock->ComputerName ); 00345 00346 RtlInitUnicodeString( &dnsNameString, LoaderBlock->SetupLoaderBlock->ComputerName ); 00347 00348 status = RtlDnsHostNameToComputerName( 00349 &netbiosNameString, 00350 &dnsNameString, 00351 TRUE); // allocate netbiosNameString 00352 00353 if ( !NT_SUCCESS(status) ) { 00354 KdPrint(( "IopAddRemoteBootValuesToRegistry: Failed RtlDnsHostNameToComputerName: %x\n", status )); 00355 goto cleanup; 00356 } 00357 00358 // 00359 // Add a value for the computername. 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 // Add a value for the host name. 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 // If the UNC path to the system files is supplied then store it in the registry. 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, '\\' ); // find last separator 00459 if ( (p != NULL) && (*(p+1) == 0) ) { 00460 00461 // 00462 // NtBootPathName ends with a backslash, so we need to back up 00463 // to the previous backslash. 00464 // 00465 00466 q = p; 00467 *q = 0; 00468 p = strrchr( LoaderBlock->NtBootPathName, '\\' ); // find last separator 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; // terminate \server\share\images\machine 00477 00478 #if defined(REMOTE_BOOT) 00479 // 00480 // Store the server path in the shared user data area. Note that we need 00481 // to add an extra \ at the beginning of this path to make it a UNC name. 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 ); // append \server\share\images\machine 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 // Disable CSC for this boot. 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 // Only disabled for last boot so re-enable now. 00607 status = NtDeleteValueKey( handle, &string); 00608 // BUGBUG should we repin? 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 // Add registry values for the IP address and subnet mask received 00624 // from DHCP. These are stored under the Tcpip service key and are 00625 // read by both Tcpip and Netbt. The adapter name used is the known 00626 // GUID for the NetbootCard. 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 // Create the service key for the netboot card. We need to have 00681 // the Type value there or the card won't be initialized. 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 // disposition 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 // Store the image path. 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 // Store the type. 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 }

VOID IopAssignNetworkDriveLetter PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 1546 of file netboot.c.

References _SETUP_LOADER_BLOCK::Flags, IoCreateSymbolicLink(), KeBugCheck(), L, NT_SUCCESS, _LOADER_PARAMETER_BLOCK::NtBootPathName, NTSTATUS(), NULL, RtlAnsiStringToUnicodeString(), RtlFreeUnicodeString(), RtlInitAnsiString(), RtlInitUnicodeString(), SETUPBLK_FLAGS_REMOTE_INSTALL, SETUPBLK_FLAGS_SYSPREP_INSTALL, _LOADER_PARAMETER_BLOCK::SetupLoaderBlock, and TRUE.

Referenced by IopStartNetworkForRemoteBoot().

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 // Create the symbolic link of X: to the redirector. We do this 01560 // after the redirector has loaded, but before AssignDriveLetters 01561 // is called the first time in textmode setup (once that has 01562 // happened, the drive letters will stick). 01563 // 01564 // Note that we use X: for the textmode setup phase of a remote 01565 // installation. But for a true remote boot, we use C:. 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 // If this is a remote boot setup boot, NtBootPathName is of the 01577 // form <server><share>\setup<install-directory><platform>. 01578 // We want the root of the X: drive to be the root of the install 01579 // directory. 01580 // 01581 // If this is a normal remote boot, NtBootPathName is of the form 01582 // <server><share>\images<machine>\winnt. We want the root of 01583 // the X: drive to be the root of the machine directory. 01584 // 01585 // Thus in either case, we need to remove the last element of the 01586 // path. 01587 // 01588 01589 p = strrchr( LoaderBlock->NtBootPathName, '\\' ); // find last separator 01590 if ( (p != NULL) && (*(p+1) == 0) ) { 01591 01592 // 01593 // NtBootPathName ends with a backslash, so we need to back up 01594 // to the previous backslash. 01595 // 01596 01597 q = p; 01598 *q = 0; 01599 p = strrchr( LoaderBlock->NtBootPathName, '\\' ); // find last separator 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; // terminate \server\share\images\machine 01607 01608 strcpy( ntName, "\\Device\\LanmanRedirector"); 01609 strcat( ntName, LoaderBlock->NtBootPathName ); // append \server\share\images\machine 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 // DbgPrint("IopAssignNetworkDriveLetter: assigned %wZ to %wZ\n", &unicodeString2, &unicodeString); 01620 01621 RtlFreeUnicodeString( &unicodeString ); 01622 01623 *p = '\\'; // restore string 01624 01625 return; 01626 }

VOID IopAssignNetworkDriveLetter IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

NTSTATUS IopCacheNetbiosNameForIpAddress IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 4247 of file netboot.c.

References ASSERT, BYTE, DWORD, Handle, htonl(), L, NT_SUCCESS, NtClose(), NtCreateFile(), NtDeviceIoControlFile(), NTSTATUS(), NULL, RtlInitUnicodeString(), Size, and Status.

Referenced by IopStartNetworkForRemoteBoot().

04252 : 04253 04254 This function takes an IP address, and submits it to NetBt for name resolution. 04255 04256 Arguments: 04257 04258 IpAddress - Address to resolve 04259 04260 Return Value: 04261 04262 Error Code. 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 // Open NetBT. 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 // Get the server's name. 04314 // 04315 // If this is a remote boot setup boot, NtBootPathName is of the 04316 // form <server><share>\setup<install-directory><platform>. 04317 // If this is a normal remote boot, NtBootPathName is of the form 04318 // <server><share>\images<machine>\winnt. 04319 // 04320 // Thus in either case, we need to isolate the first element of the 04321 // path. 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 // Fill in the tREMOTE_CACHE structure. 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 // Submit the IOCTL. 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 }

BOOLEAN IopIsRemoteBootCard IN PDEVICE_NODE  DeviceNode,
IN PLOADER_PARAMETER_BLOCK  LoaderBlock,
IN PWCHAR  HwIds
 

Definition at line 1903 of file netboot.c.

References BusNumber, FALSE, L, _SETUP_LOADER_BLOCK::NetbootCardHardwareId, _SETUP_LOADER_BLOCK::NetbootCardInfo, PSETUP_LOADER_BLOCK, and TRUE.

Referenced by IopProcessNewDeviceNode().

01911 : 01912 01913 This function determines if the card described by the hwIds is the 01914 remote boot network card. It checks against the hardware ID for the 01915 card that is stored in the setup loader block. 01916 01917 THIS ASSUMES THAT IOREMOTEBOOTCLIENT IS TRUE AND THAT LOADERBLOCK 01918 IS VALID. 01919 01920 Arguments: 01921 01922 DeviceNode - Device node for the card in question. 01923 01924 LoaderBlock - Supplies a pointer to the loader parameter block that was 01925 created by the OS Loader. 01926 01927 HwIds - The hardware IDs for the device in question. 01928 01929 Return Value: 01930 01931 TRUE or FALSE. 01932 01933 --*/ 01934 01935 { 01936 PSETUP_LOADER_BLOCK setupLoaderBlock; 01937 PWCHAR curHwId; 01938 01939 // 01940 // setupLoaderBlock will always be non-NULL if we are 01941 // remote booting, even if we are not in setup. 01942 // 01943 01944 setupLoaderBlock = LoaderBlock->SetupLoaderBlock; 01945 01946 // 01947 // Scan through the HwIds for a match. 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 }

NTSTATUS IopSetDefaultGateway IN ULONG  GatewayAddress  ) 
 

Definition at line 4017 of file netboot.c.

References BYTE, DEFAULT_DEST, DEFAULT_DEST_MASK, DEFAULT_METRIC, DWORD, ExAllocatePoolWithTag, ExFreePool(), Handle, ID, IopTCPQueryInformationEx(), IopTCPSetInformationEx(), NT_SUCCESS, NtClose(), NtCreateFile(), NTSTATUS(), NULL, PagedPool, RtlInitUnicodeString(), Size, and Status.

Referenced by IopStartNetworkForRemoteBoot().

04022 : 04023 04024 This function adds a default gateway entry from the router table. 04025 04026 Arguments: 04027 04028 GatewayAddress - Address of the default gateway. 04029 04030 Return Value: 04031 04032 Error Code. 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 // Get the NetAddr info, to find an interface index for the gateway. 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 // We've got the address table. Loop through it. If we find an exact 04138 // match for the gateway, then we're adding or deleting a direct route 04139 // and we're done. Otherwise try to find a match on the subnet mask, 04140 // and remember the first one we find. 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 // Found an exact match. 04150 // 04151 04152 MatchIndex = i; 04153 Type = IRE_TYPE_DIRECT; 04154 break; 04155 } 04156 04157 // 04158 // The next hop is on the same subnet as this address. If 04159 // we haven't already found a match, remember this one. 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 // We've looked at all of the entries. See if we found a match. 04174 // 04175 04176 if (MatchIndex == 0xffff) { 04177 // 04178 // Didn't find a match. 04179 // 04180 04181 Status = STATUS_UNSUCCESSFUL; 04182 KdPrint(( "IopSetDefaultGateway: Unable to find match for gateway\n" )); 04183 goto Cleanup; 04184 } 04185 04186 // 04187 // We've found a match. Fill in the route entry, and call the 04188 // Set API. 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 }

NTSTATUS IopSetupRemoteBootCard IN PLOADER_PARAMETER_BLOCK  LoaderBlock,
IN HANDLE  UniqueIdHandle,
IN PUNICODE_STRING  UnicodeDeviceInstance
 

Definition at line 1982 of file netboot.c.

References CmRegistryMachineSystemCurrentControlSet, CmRegistryMachineSystemCurrentControlSetControlClass, FALSE, IopOpenRegistryKey(), IopRemoteBootCardInitialized, L, _SETUP_LOADER_BLOCK::NetbootCardDriverName, _SETUP_LOADER_BLOCK::NetbootCardHardwareId, _SETUP_LOADER_BLOCK::NetbootCardInfo, _SETUP_LOADER_BLOCK::NetbootCardRegistry, _SETUP_LOADER_BLOCK::NetbootCardServiceName, NT_SUCCESS, NTSTATUS(), NULL, RtlAnsiStringToUnicodeString(), RtlEqualUnicodeString(), RtlInitAnsiString(), RtlInitString(), RtlInitUnicodeString(), strlen(), TITLE_INDEX_VALUE, and TRUE.

Referenced by IopProcessNewDeviceNode().

01990 : 01991 01992 This function modifies the registry to set up the netboot card. 01993 We must do this here since the card is needed to boot, we can't 01994 wait for the class installer to run. 01995 01996 THIS ASSUMES THAT IOREMOTEBOOTCLIENT IS TRUE. 01997 01998 Arguments: 01999 02000 LoaderBlock - Supplies a pointer to the loader parameter block that was 02001 created by the OS Loader. 02002 02003 UniqueIdHandle - A handle to the device's unique node under the 02004 Enum key. 02005 02006 UnicodeDeviceInstance - The device instance assigned to the device. 02007 02008 Return Value: 02009 02010 Status of the operation. 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 // If we already think we have initialized a remote boot card, then 02038 // exit (should not really happen once we identify cards using the 02039 // bus/slot. 02040 // 02041 02042 if (IopRemoteBootCardInitialized) { 02043 return STATUS_SUCCESS; 02044 } 02045 02046 // 02047 // setupLoaderBlock will always be non-NULL if we are 02048 // remote booting, even if we are not in setup. 02049 // 02050 02051 setupLoaderBlock = LoaderBlock->SetupLoaderBlock; 02052 02053 // 02054 // Open the current control set. 02055 // 02056 02057 status = IopOpenRegistryKey(&currentControlSetHandle, 02058 NULL, 02059 &CmRegistryMachineSystemCurrentControlSet, 02060 KEY_ALL_ACCESS, 02061 FALSE 02062 ); 02063 02064 if (!NT_SUCCESS(status)) { 02065 goto cleanup; 02066 } 02067 02068 // 02069 // Open the Control\RemoteBoot key, which may not exist. 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 // Open the key where the netui code stores information about the cards. 02096 // During textmode setup this will fail because the Control\Network 02097 // key is not there. After that it should work, although we may need 02098 // to create the last node in the path. 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 // If the PnpInstanceID of the first netboot card matches the one 02123 // for this device node, and the NET_CARD_INFO that the loader 02124 // found is the same as the one we saved, then this is the same 02125 // card with the same instance ID as before, so we don't need to 02126 // do anything. 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 // Check that it matches. We can init the string because we zeroed 02143 // the dataBuffer before reading the key, so even if the 02144 // registry value had no NULL at the end that is OK. 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 // Instance ID matched, see if the NET_CARD_INFO matches. 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 // Everything matched, so no need to do any setup. 02176 // 02177 02178 status = STATUS_SUCCESS; 02179 goto cleanup; 02180 02181 } 02182 } 02183 } 02184 } 02185 02186 02187 // 02188 // We come through here if the saved registry data was missing or 02189 // not correct. Write all the relevant values to the registry. 02190 // 02191 02192 02193 // 02194 // Service name is in the loader block. 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 // ClassGUID is the known net card GUID. 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 // Driver is the first net card. 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 // Identify this as the netboot card so the network class 02235 // installer knows to assign the reserved GUID. 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 // The ConfigFlags value exists in the registry 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 // Open a handle for card parameters. We write RemoteBootCard plus 02272 // whatever the BINL server told us to write. 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(&parametersHandle, 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 // We know that this is a different NIC, so remove all the old parameters. 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 // We don't delete "NetCfgInstanceID", it won't change and 02331 // its presence signifies to the net class installer that 02332 // this is a replacement not a clean install. 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; // leave NetCfgInstanceID at index 0 02350 } 02351 02352 } 02353 02354 // 02355 // Write a parameter called RemoteBootCard set to TRUE, this 02356 // is primarily so NDIS can recognize this as such. 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 // Store any other parameters sent from the server. 02372 // 02373 02374 registryList = setupLoaderBlock->NetbootCardRegistry; 02375 02376 if (registryList != NULL) { 02377 02378 STRING aString; 02379 UNICODE_STRING uString, uString2; 02380 02381 // 02382 // The registry list is a series of name\0type\0value\0, with 02383 // a final \0 at the end. It is in ANSI, not UNICODE. 02384 // 02385 // All values are stored under parametersHandle. Type is 1 for 02386 // DWORD and 2 for SZ. 02387 // 02388 02389 uString.Buffer = tempNameBuffer; 02390 uString.MaximumLength = sizeof(tempNameBuffer); 02391 02392 while (*registryList != '\0') { 02393 02394 // 02395 // First the name. 02396 // 02397 02398 RtlInitString(&aString, registryList); 02399 RtlAnsiStringToUnicodeString(&uString, &aString, FALSE); 02400 02401 // 02402 // Now the type. 02403 // 02404 02405 registryList += (strlen(registryList) + 1); 02406 02407 if (*registryList == '1') { 02408 02409 // 02410 // A DWORD, parse it. 02411 // 02412 02413 registryList += 2; // skip "1\0" 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 // An SZ, convert to Unicode. 02435 // 02436 02437 registryList += 2; // skip "2\0" 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 // Not "1" or "2", so stop processing registryList. 02458 // 02459 02460 break; 02461 02462 } 02463 02464 } 02465 02466 } 02467 02468 // 02469 // Save the NET_CARD_INFO so we can check it next time. 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 // Save the hardware ID, driver name, and service name, 02485 // so the loader can read those if the server is down 02486 // on subsequent boots. 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 // Save the device instance, in case we need to ID the card later. 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 // Make sure we only pick one card to setup this way! 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 }

NTSTATUS IopStartNetworkForRemoteBoot PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 770 of file netboot.c.

References ASSERT, _SETUP_LOADER_BLOCK::DefaultRouter, ExAllocatePoolWithTag, ExFreePool(), FALSE, _SETUP_LOADER_BLOCK::Flags, IoGetCurrentProcess(), IopAssignNetworkDriveLetter(), IopCacheNetbiosNameForIpAddress(), IopSetDefaultGateway(), KeDelayExecutionThread(), KernelMode, L, max, MAX_PATH, _SETUP_LOADER_BLOCK::NetbootCardDriverName, _SETUP_LOADER_BLOCK::NetBootSecret, NonPagedPool, NT_SUCCESS, NtClose(), NtCreateFile(), NtDeviceIoControlFile(), NtFsControlFile(), NtOpenKey(), NtQueryValueKey(), NTSTATUS(), NULL, _EPROCESS::Pcb, RtlCreateUnicodeString(), RtlFreeUnicodeString(), RtlInitUnicodeString(), SETUPBLK_FLAGS_IS_TEXTMODE, _LOADER_PARAMETER_BLOCK::SetupLoaderBlock, and TRUE.

Referenced by IoInitSystem().

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 // Initialize for cleanup. 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 // Allocate a temporary buffer. It has to be big enough for all the 00818 // various FSCTLs we send down. 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 // Open the redirector and the datagram receiver. 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 // If the setup loader block has a disk secret in it provided by the 00917 // loader, pass this down to the redirector (do this before sending 00918 // the LMR_START, since that uses this information). 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 // Read the computer name and domain name from the registry so we 00960 // can give them to the datagram receiver. During textmode setup 00961 // the domain name will not be there, so we won't start the datagram 00962 // receiver, which is fine. 00963 // 00964 // BUGBUG: Figure out the correct location to read the domain name 00965 // from -- this one is a special hack in winnt.sif just for this. 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 // Tell the redir to start. 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 // Tell the datagram receiver to start. 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 // Tell the redir to bind to the transports. 01181 // 01182 // Note: In the current redirector implementation, this call just 01183 // tells the redirector to register for TDI PnP notifications. 01184 // Starting the datagram receiver also does this, so we only issue 01185 // this FSCTL if we're not starting the datagram receiver. 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 // Get the path to the boot partition on the disk for CSC and redirection 01217 // Note: On failure, this defaults to \Device\Harddisk0\Partition1 01218 // 01219 01220 IopGetHarddiskInfo(NetHDCSCPartition); 01221 01222 // 01223 // Tell the redirector to initialize remote boot redirection (back 01224 // to the local disk). Note that we only do this if we're NOT doing 01225 // textmode setup. During textmode, we let Setup do this so that it 01226 // can do so AFTER it has reformatted the local disk. 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 // Loop until the redirector is bound to the transport. It may take a 01257 // while because TDI defers notification of binding to a worker thread. 01258 // We start with a half a second wait and double it each time, trying 01259 // five times total. 01260 // 01261 01262 interval.QuadPart = -500 * 1000 * 10; // 1/2 second, relative 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 //KdPrint(( "IopStartNetworkForRemoteBoot: Unable to FSCTL(enumerate) redirector: %x\n", status )); 01292 } else if (rrp->Parameters.Get.TotalBytesNeeded == 0) { 01293 //KdPrint(( "IopStartNetworkForRemoteBoot: FSCTL(enumerate) returned 0 entries\n" )); 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 // Prime the transport. 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 // CSC needs to be initialized after binding to the transport because ResetCSC 01324 // (if needed) will try to enumerate the files and directories on the server. 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 // If we are connected and either we are part way through a reset of 01341 // the csc or the init failed then reset the csc. 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 // CSC may have lost the pin information. 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 // if we are connected and we're not repinning all files and 01367 // we have a new net card driver to pin, then pin it below 01368 // after we've created called IopAssignNetworkDriveLetter 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 // Pin the new net card driver simply by opening it. if it 01394 // fails, it's not fatal, as we'll eventually pin it since 01395 // the directory it's in is marked as system/inherit. 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 // this is not a fatal error, the redir should pin it eventually 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 // this is not a fatal error, the redir should pin it eventually 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 // If requested, exit with RdrHandle still set so that we can close CSC quickly. 01484 // 01485 01486 if ( !leaveRdrHandleOpen && (RdrHandle != NULL) ) { 01487 NtClose( RdrHandle ); 01488 RdrHandle = NULL; 01489 } 01490 #endif // defined(REMOTE_BOOT) 01491 01492 return status; 01493 }

NTSTATUS IopStartTcpIpForRemoteBoot PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 1834 of file netboot.c.

References _SETUP_LOADER_BLOCK::IpAddress, NT_SUCCESS, NtClose(), NtCreateFile(), NtDeviceIoControlFile(), NTSTATUS(), NULL, RtlInitUnicodeString(), _LOADER_PARAMETER_BLOCK::SetupLoaderBlock, _SETUP_LOADER_BLOCK::SubnetMask, and USHORT.

Referenced by IopInitializeBootDrivers().

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 }

NTSTATUS IopTCPQueryInformationEx IN HANDLE  TCPHandle,
IN TDIObjectID FAR *  ID,
OUT void FAR *  Buffer,
IN OUT DWORD FAR *  BufferSize,
IN OUT BYTE FAR *  Context
 

Definition at line 4377 of file netboot.c.

References ASSERT, Buffer, BufferSize, DWORD, ID, NT_SUCCESS, NtDeviceIoControlFile(), NTSTATUS(), and NULL.

Referenced by IopSetDefaultGateway().

04386 : 04387 04388 This routine provides the interface to the TDI QueryInformationEx 04389 facility of the TCP/IP stack on NT. Someday, this facility will be 04390 part of TDI. 04391 04392 Arguments: 04393 04394 TCPHandle - Open handle to the TCP driver 04395 ID - The TDI Object ID to query 04396 Buffer - Data buffer to contain the query results 04397 BufferSize - Pointer to the size of the results buffer. Filled in 04398 with the amount of results data on return. 04399 Context - Context value for the query. Should be zeroed for a 04400 new query. It will be filled with context 04401 information for linked enumeration queries. 04402 04403 Return Value: 04404 04405 An NTSTATUS value. 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, // Driver handle 04426 NULL, // Event 04427 NULL, // APC Routine 04428 NULL, // APC context 04429 &ioStatusBlock, // Status block 04430 IOCTL_TCP_QUERY_INFORMATION_EX, // Control code 04431 &queryBuffer, // Input buffer 04432 queryBufferSize, // Input buffer size 04433 Buffer, // Output buffer 04434 *BufferSize // Output buffer size 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 // Copy the return context to the caller's context buffer 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 }

NTSTATUS IopTCPSetInformationEx IN HANDLE  TCPHandle,
IN TDIObjectID FAR *  ID,
IN void FAR *  Buffer,
IN DWORD FAR  BufferSize
 

Definition at line 4458 of file netboot.c.

References ASSERT, Buffer, BufferSize, DWORD, ExAllocatePoolWithTag, ExFreePool(), ID, NT_SUCCESS, NtDeviceIoControlFile(), NTSTATUS(), NULL, and PagedPool.

Referenced by IopSetDefaultGateway().

04466 : 04467 04468 This routine provides the interface to the TDI SetInformationEx 04469 facility of the TCP/IP stack on NT. Someday, this facility will be 04470 part of TDI. 04471 04472 Arguments: 04473 04474 TCPHandle - Open handle to the TCP driver 04475 ID - The TDI Object ID to set 04476 Buffer - Data buffer containing the information to be set 04477 BufferSize - The size of the set data buffer. 04478 04479 Return Value: 04480 04481 An NTSTATUS value. 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, // Driver handle 04512 NULL, // Event 04513 NULL, // APC Routine 04514 NULL, // APC context 04515 &ioStatusBlock, // Status block 04516 IOCTL_TCP_SET_INFORMATION_EX, // Control code 04517 setBuffer, // Input buffer 04518 setBufferSize, // Input buffer size 04519 NULL, // Output buffer 04520 0 // Output buffer size 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 }

NTSTATUS IopWriteIpAddressToRegistry HANDLE  handle,
PWCHAR  regkey,
PUCHAR  value
 

Definition at line 3974 of file netboot.c.

References CHAR, FALSE, NT_SUCCESS, NtSetValueKey(), NTSTATUS(), RtlAnsiStringToUnicodeString(), RtlInitAnsiString(), RtlInitUnicodeString(), and sprintf().

Referenced by IopAddRemoteBootValuesToRegistry().

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 }


Variable Documentation

BOOLEAN ExpInTextModeSetup
 

Definition at line 53 of file netboot.c.


Generated on Sat May 15 19:44:50 2004 for test by doxygen 1.3.7