BOOL WINAPI IsValidDevmodeW(PDEVMODEW pDevmode, size_t DevmodeSize) { PMINIMUM_SIZE_TABLE pTable = MinimumSizeW; WORD wRequiredSize; TRACE("IsValidDevmodeW(%p, %lu)\n", pDevmode, DevmodeSize); // Check if a Devmode was given at all. if (!pDevmode) goto Failure; // Verify that DevmodeSize is large enough to hold the public and private members of the structure. if (DevmodeSize < pDevmode->dmSize + pDevmode->dmDriverExtra) goto Failure; // If the structure has private members, the public structure must be 32-bit packed. if (pDevmode->dmDriverExtra && pDevmode->dmSize % 4) goto Failure; // Now determine the minimum possible dmSize based on the given fields in dmFields. wRequiredSize = FIELD_OFFSET(DEVMODEW, dmFields) + RTL_FIELD_SIZE(DEVMODEW, dmFields); while (pTable->dwField) { if (pDevmode->dmFields & pTable->dwField) { wRequiredSize = pTable->wSize; break; } pTable++; } // Verify that the value in dmSize is big enough for the used fields. if (pDevmode->dmSize < wRequiredSize) goto Failure; // Check if dmDeviceName and (if used) dmFormName are null-terminated. // Fix this if they aren't. _FixStringW(pDevmode->dmDeviceName, sizeof(pDevmode->dmDeviceName)); if (pDevmode->dmFields & DM_FORMNAME) _FixStringW(pDevmode->dmFormName, sizeof(pDevmode->dmFormName)); // Return success without setting the error code. return TRUE; Failure: SetLastError(ERROR_INVALID_DATA); return FALSE; }
NTSTATUS NTAPI ConDrvWriteConsoleOutputString(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN CODE_TYPE CodeType, IN PVOID StringBuffer, IN ULONG NumCodesToWrite, IN PCOORD WriteCoord, // OUT PCOORD EndCoord, OUT PULONG NumCodesWritten OPTIONAL) { NTSTATUS Status = STATUS_SUCCESS; PVOID WriteBuffer = NULL; PWCHAR tmpString = NULL; ULONG X, Y, Length; // , Written = 0; ULONG CodeSize; PCHAR_INFO Ptr; if (Console == NULL || Buffer == NULL || WriteCoord == NULL /* || EndCoord == NULL */) { return STATUS_INVALID_PARAMETER; } /* Validity checks */ ASSERT(Console == Buffer->Header.Console); ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToWrite == 0)); // // FIXME: Make overflow checks on WriteCoord !!!!!! // if (NumCodesWritten) *NumCodesWritten = 0; switch (CodeType) { case CODE_ASCII: CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar); break; case CODE_UNICODE: CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar); break; case CODE_ATTRIBUTE: CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute); break; default: return STATUS_INVALID_PARAMETER; } if (CodeType == CODE_ASCII) { /* Convert the ASCII string into Unicode before writing it to the console */ Length = MultiByteToWideChar(Console->OutputCodePage, 0, (PCHAR)StringBuffer, NumCodesToWrite, NULL, 0); tmpString = WriteBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); if (WriteBuffer) { MultiByteToWideChar(Console->OutputCodePage, 0, (PCHAR)StringBuffer, NumCodesToWrite, (PWCHAR)WriteBuffer, Length); } else { Status = STATUS_NO_MEMORY; } // FIXME: Quick fix: fix the CodeType and CodeSize since the // ASCII string was converted into UNICODE. // A proper fix needs to be written. CodeType = CODE_UNICODE; CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar); } else { /* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */ WriteBuffer = StringBuffer; } if (WriteBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup; X = WriteCoord->X; Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; Length = NumCodesToWrite; // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work while (Length--) { // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; switch (CodeType) { case CODE_ASCII: case CODE_UNICODE: Ptr->Char.UnicodeChar = *(PWCHAR)WriteBuffer; break; case CODE_ATTRIBUTE: Ptr->Attributes = *(PWORD)WriteBuffer; break; } WriteBuffer = (PVOID)((ULONG_PTR)WriteBuffer + CodeSize); // ++Ptr; // Written++; if (++X == Buffer->ScreenBufferSize.X) { X = 0; if (++Y == Buffer->ScreenBufferSize.Y) { Y = 0; } } } if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) { SMALL_RECT UpdateRect; ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite); TermDrawRegion(Console, &UpdateRect); } // EndCoord->X = X; // EndCoord->Y = (Y + Buffer->ScreenBufferSize.Y - Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; Cleanup: if (tmpString) RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString); if (NumCodesWritten) *NumCodesWritten = NumCodesToWrite; // Written; return Status; }
NTSTATUS NTAPI ConDrvReadConsoleOutputString(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN CODE_TYPE CodeType, OUT PVOID StringBuffer, IN ULONG NumCodesToRead, IN PCOORD ReadCoord, // OUT PCOORD EndCoord, OUT PULONG NumCodesRead OPTIONAL) { SHORT Xpos, Ypos; PVOID ReadBuffer; ULONG i; ULONG CodeSize; PCHAR_INFO Ptr; if (Console == NULL || Buffer == NULL || ReadCoord == NULL /* || EndCoord == NULL */) { return STATUS_INVALID_PARAMETER; } /* Validity checks */ ASSERT(Console == Buffer->Header.Console); ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToRead == 0)); // // FIXME: Make overflow checks on ReadCoord !!!!!! // if (NumCodesRead) *NumCodesRead = 0; switch (CodeType) { case CODE_ASCII: CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar); break; case CODE_UNICODE: CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar); break; case CODE_ATTRIBUTE: CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute); break; default: return STATUS_INVALID_PARAMETER; } ReadBuffer = StringBuffer; Xpos = ReadCoord->X; Ypos = (ReadCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; /* * MSDN (ReadConsoleOutputAttribute and ReadConsoleOutputCharacter) : * * If the number of attributes (resp. characters) to be read from extends * beyond the end of the specified screen buffer row, attributes (resp. * characters) are read from the next row. If the number of attributes * (resp. characters) to be read from extends beyond the end of the console * screen buffer, attributes (resp. characters) up to the end of the console * screen buffer are read. * * TODO: Do NOT loop up to NumCodesToRead, but stop before * if we are going to overflow... */ // Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); // Doesn't work for (i = 0; i < min(NumCodesToRead, (ULONG)Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y); ++i) { // Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); // Doesn't work either Ptr = &Buffer->Buffer[Xpos + Ypos * Buffer->ScreenBufferSize.X]; switch (CodeType) { case CODE_ASCII: ConsoleOutputUnicodeToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar); break; case CODE_UNICODE: *(PWCHAR)ReadBuffer = Ptr->Char.UnicodeChar; break; case CODE_ATTRIBUTE: *(PWORD)ReadBuffer = Ptr->Attributes; break; } ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize); // ++Ptr; Xpos++; if (Xpos == Buffer->ScreenBufferSize.X) { Xpos = 0; Ypos++; if (Ypos == Buffer->ScreenBufferSize.Y) { Ypos = 0; } } } // EndCoord->X = Xpos; // EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % Buffer->ScreenBufferSize.Y; if (NumCodesRead) *NumCodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / CodeSize; // <= NumCodesToRead return STATUS_SUCCESS; }
static VOID RSSCalcHash_Unsafe( PARANDIS_RSS_PARAMS *RSSParameters, PVOID dataBuffer, PNET_PACKET_INFO packetInfo) { HASH_CALC_SG_BUF_ENTRY sgBuff[3]; ULONG hashTypes = NDIS_RSS_HASH_TYPE_FROM_HASH_INFO(RSSParameters->ActiveHashingSettings.HashInformation); if(packetInfo->isIP4) { if(packetInfo->isTCP && (hashTypes & NDIS_HASH_TCP_IPV4)) { IPv4Header *pIpHeader = (IPv4Header *) RtlOffsetToPointer(dataBuffer, packetInfo->L2HdrLen); TCPHeader *pTCPHeader = (TCPHeader *) RtlOffsetToPointer(pIpHeader, packetInfo->L3HdrLen); sgBuff[0].chunkPtr = RtlOffsetToPointer(pIpHeader, FIELD_OFFSET(IPv4Header, ip_src)); sgBuff[0].chunkLen = RTL_FIELD_SIZE(IPv4Header, ip_src) + RTL_FIELD_SIZE(IPv4Header, ip_dest); sgBuff[1].chunkPtr = RtlOffsetToPointer(pTCPHeader, FIELD_OFFSET(TCPHeader, tcp_src)); sgBuff[1].chunkLen = RTL_FIELD_SIZE(TCPHeader, tcp_src) + RTL_FIELD_SIZE(TCPHeader, tcp_dest); packetInfo->RSSHash.Value = ToeplitsHash(sgBuff, 2, &RSSParameters->ActiveHashingSettings.HashSecretKey[0]); packetInfo->RSSHash.Type = NDIS_HASH_TCP_IPV4; packetInfo->RSSHash.Function = NdisHashFunctionToeplitz; return; } if(hashTypes & NDIS_HASH_IPV4) { sgBuff[0].chunkPtr = RtlOffsetToPointer(dataBuffer, packetInfo->L2HdrLen + FIELD_OFFSET(IPv4Header, ip_src)); sgBuff[0].chunkLen = RTL_FIELD_SIZE(IPv4Header, ip_src) + RTL_FIELD_SIZE(IPv4Header, ip_dest); packetInfo->RSSHash.Value = ToeplitsHash(sgBuff, 1, RSSParameters->ActiveHashingSettings.HashSecretKey); packetInfo->RSSHash.Type = NDIS_HASH_IPV4; packetInfo->RSSHash.Function = NdisHashFunctionToeplitz; return; } } else if(packetInfo->isIP6) { if(packetInfo->isTCP) { if(hashTypes & (NDIS_HASH_TCP_IPV6 | NDIS_HASH_TCP_IPV6_EX)) { IPv6Header *pIpHeader = (IPv6Header *) RtlOffsetToPointer(dataBuffer, packetInfo->L2HdrLen); TCPHeader *pTCPHeader = (TCPHeader *) RtlOffsetToPointer(pIpHeader, packetInfo->L3HdrLen); sgBuff[0].chunkPtr = (PCHAR) GetIP6SrcAddrForHash(dataBuffer, packetInfo, hashTypes); sgBuff[0].chunkLen = RTL_FIELD_SIZE(IPv6Header, ip6_src_address); sgBuff[1].chunkPtr = (PCHAR) GetIP6DstAddrForHash(dataBuffer, packetInfo, hashTypes); sgBuff[1].chunkLen = RTL_FIELD_SIZE(IPv6Header, ip6_dst_address); sgBuff[2].chunkPtr = RtlOffsetToPointer(pTCPHeader, FIELD_OFFSET(TCPHeader, tcp_src)); sgBuff[2].chunkLen = RTL_FIELD_SIZE(TCPHeader, tcp_src) + RTL_FIELD_SIZE(TCPHeader, tcp_dest); packetInfo->RSSHash.Value = ToeplitsHash(sgBuff, 3, RSSParameters->ActiveHashingSettings.HashSecretKey); packetInfo->RSSHash.Type = (hashTypes & NDIS_HASH_TCP_IPV6_EX) ? NDIS_HASH_TCP_IPV6_EX : NDIS_HASH_TCP_IPV6; packetInfo->RSSHash.Function = NdisHashFunctionToeplitz; return; } } if(hashTypes & (NDIS_HASH_IPV6 | NDIS_HASH_IPV6_EX)) { sgBuff[0].chunkPtr = (PCHAR) GetIP6SrcAddrForHash(dataBuffer, packetInfo, hashTypes); sgBuff[0].chunkLen = RTL_FIELD_SIZE(IPv6Header, ip6_src_address); sgBuff[1].chunkPtr = (PCHAR) GetIP6DstAddrForHash(dataBuffer, packetInfo, hashTypes); sgBuff[1].chunkLen = RTL_FIELD_SIZE(IPv6Header, ip6_dst_address); packetInfo->RSSHash.Value = ToeplitsHash(sgBuff, 2, RSSParameters->ActiveHashingSettings.HashSecretKey); packetInfo->RSSHash.Type = (hashTypes & NDIS_HASH_IPV6_EX) ? NDIS_HASH_IPV6_EX : NDIS_HASH_IPV6; packetInfo->RSSHash.Function = NdisHashFunctionToeplitz; return; } if(hashTypes & NDIS_HASH_IPV6) { IPv6Header *pIpHeader = (IPv6Header *) RtlOffsetToPointer(dataBuffer, packetInfo->L2HdrLen); sgBuff[0].chunkPtr = RtlOffsetToPointer(pIpHeader, FIELD_OFFSET(IPv6Header, ip6_src_address)); sgBuff[0].chunkLen = RTL_FIELD_SIZE(IPv6Header, ip6_src_address) + RTL_FIELD_SIZE(IPv6Header, ip6_dst_address); packetInfo->RSSHash.Value = ToeplitsHash(sgBuff, 2, RSSParameters->ActiveHashingSettings.HashSecretKey); packetInfo->RSSHash.Type = NDIS_HASH_IPV6; packetInfo->RSSHash.Function = NdisHashFunctionToeplitz; return; } } packetInfo->RSSHash.Value = 0; packetInfo->RSSHash.Type = 0; packetInfo->RSSHash.Function = 0; }
NTSTATUS ModifySelfSizeOfImage(LPWSTR ExeFullPath, LPWSTR CommandLine, ULONG SizeOfImage) { BOOL Result; ULONG Length; PVOID FakeCPInfoBuffer; WCHAR CmdFullPath[MAX_NTPATH]; PWCHAR CmdLineBuffer; NTSTATUS Status; PLDR_MODULE LdrModule; PIMAGE_DOS_HEADER DosHeader; PIMAGE_NT_HEADERS NtHeader; PIMAGE_SECTION_HEADER SectionHeader; FAKE_CREATE_PROCESS_INFO *fcpi; PROCESS_INFORMATION ProcessInformation; CONTEXT Context; NtFileDisk file; UNICODE_STRING ExeNtPath, *ProcessCommandLine; UNREFERENCED_PARAMETER(CommandLine); LdrModule = Nt_FindLdrModuleByName(NULL); DosHeader = (PIMAGE_DOS_HEADER)&__ImageBase; NtHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew); fcpi = (FAKE_CREATE_PROCESS_INFO *)AllocStack(0x2000); fcpi->PeHeaderSize = (ULONG_PTR)(IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections) - (ULONG_PTR)DosHeader; Status = file.Open(LdrModule->FullDllName.Buffer); if (!NT_SUCCESS(Status)) return Status; Status = file.Read(fcpi->PeHeader, fcpi->PeHeaderSize); if (!NT_SUCCESS(Status)) return Status; CmdLineBuffer = (PWCHAR)((ULONG_PTR)fcpi->PeHeader + fcpi->PeHeaderSize); fcpi->CommandLine.Buffer = CmdLineBuffer; fcpi->CommandLine.Length = (USHORT)(StrLengthW(ExeFullPath) * sizeof(WCHAR)); ProcessCommandLine = &Nt_CurrentPeb()->ProcessParameters->CommandLine; CopyMemory(CmdLineBuffer, ProcessCommandLine->Buffer, ProcessCommandLine->Length); *(PULONG_PTR)&CmdLineBuffer += ProcessCommandLine->Length; CmdLineBuffer[0] = 0; fcpi->CommandLine.Length = ProcessCommandLine->Length; fcpi->CommandLine.MaximumLength = fcpi->CommandLine.Length + sizeof(WCHAR); ++CmdLineBuffer; CmdLineBuffer = (PWCHAR)ROUND_UP((ULONG_PTR)CmdLineBuffer, 16); RtlDosPathNameToNtPathName_U(LdrModule->FullDllName.Buffer, &ExeNtPath, NULL, NULL); fcpi->ExeNtPath.Buffer = CmdLineBuffer; CopyMemory(CmdLineBuffer, ExeNtPath.Buffer, ExeNtPath.Length); *(PULONG_PTR)&CmdLineBuffer += ExeNtPath.Length; CmdLineBuffer[0] = 0; fcpi->ExeNtPath.Length = ExeNtPath.Length; fcpi->ExeNtPath.MaximumLength = fcpi->ExeNtPath.Length + sizeof(WCHAR); *CmdLineBuffer++ = 0; RtlFreeUnicodeString(&ExeNtPath); DosHeader = (PIMAGE_DOS_HEADER)fcpi->PeHeader; NtHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew); SectionHeader = IMAGE_FIRST_SECTION(NtHeader); SectionHeader += NtHeader->FileHeader.NumberOfSections - 1; SizeOfImage -= LdrModule->SizeOfImage; SizeOfImage = ROUND_UP(SizeOfImage, MEMORY_PAGE_SIZE); SectionHeader->Misc.VirtualSize = ROUND_UP(SectionHeader->Misc.VirtualSize, MEMORY_PAGE_SIZE) + SizeOfImage; if (NtHeader->FileHeader.SizeOfOptionalHeader > FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, SizeOfImage) + RTL_FIELD_SIZE(IMAGE_OPTIONAL_HEADER, SizeOfImage)) NtHeader->OptionalHeader.SizeOfImage += SizeOfImage; Length = Nt_GetSystemDirectory(CmdFullPath, countof(CmdFullPath)); StrCopyW(CmdFullPath + Length, L"cmd.exe"); ProcessInformation.hProcess = NtCurrentProcess(); ProcessInformation.hThread = NtCurrentThread(); #if 1 Result = Nt_CreateProcess(NULL, CmdFullPath, NULL, CREATE_SUSPENDED, NULL, &ProcessInformation); if (!Result) return STATUS_UNSUCCESSFUL; #endif FakeCPInfoBuffer = NULL; LOOP_ONCE { ULONG_PTR Offset; Status = NtDuplicateObject( NtCurrentProcess(), NtCurrentProcess(), ProcessInformation.hProcess, &fcpi->ProcessHandle, 0, 0, DUPLICATE_SAME_ACCESS ); if (!NT_SUCCESS(Status)) break; /* Status = NtDuplicateObject( NtCurrentProcess(), file, ProcessInformation.hProcess, &fcpi->FileHandle, 0, 0, DUPLICATE_SAME_ACCESS ); if (!NT_SUCCESS(Status)) break; */ Status = Nt_AllocateMemory(ProcessInformation.hProcess, &FakeCPInfoBuffer, MEMORY_PAGE_SIZE); if (!NT_SUCCESS(Status)) break; fcpi->CreateProcessInternalW = CreateProcessInternalW; fcpi->NtTerminateProcess = NtTerminateProcess; fcpi->LdrShutdownProcess = LdrShutdownProcess; fcpi->NtCreateFile = NtCreateFile; fcpi->NtWriteFile = NtWriteFile; fcpi->NtClose = NtClose; fcpi->NtWaitForSingleObject = NtWaitForSingleObject; fcpi->InitialDirectory.Buffer = NULL; Offset = (ULONG_PTR)FakeCPInfoBuffer - (ULONG_PTR)fcpi; *(PULONG_PTR)&fcpi->CommandLine.Buffer += Offset; *(PULONG_PTR)&fcpi->ExeNtPath.Buffer += Offset; Status = Nt_WriteMemory( ProcessInformation.hProcess, FakeCPInfoBuffer, fcpi, (ULONG_PTR)CmdLineBuffer - (ULONG_PTR)fcpi, &Length ); if (!NT_SUCCESS(Status)) break; Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; Status = NtGetContextThread(ProcessInformation.hThread, &Context); if (!NT_SUCCESS(Status)) break; Context.Eip = (ULONG_PTR)FakeCPInfoBuffer + Length; Context.Eip = ROUND_UP(Context.Eip, 16); Context.Ecx = (ULONG_PTR)FakeCPInfoBuffer; Status = Nt_WriteMemory( ProcessInformation.hProcess, (PVOID)Context.Eip, ModifySizeOfImage, (ULONG_PTR)ModifySizeOfImageEnd - (ULONG_PTR)ModifySizeOfImage, &Length ); if (!NT_SUCCESS(Status)) break; #if 1 Status = NtSetContextThread(ProcessInformation.hThread, &Context); if (!NT_SUCCESS(Status)) break; Status = NtResumeThread(ProcessInformation.hThread, NULL); #else INLINE_ASM jmp Context.Eip; #endif } if (!NT_SUCCESS(Status)) { if (FakeCPInfoBuffer != NULL) Nt_FreeMemory(ProcessInformation.hProcess, FakeCPInfoBuffer); NtTerminateProcess(ProcessInformation.hProcess, 0); } NtClose(ProcessInformation.hProcess); NtClose(ProcessInformation.hThread); return Status; }
NTSTATUS GetExeImageSize(LPWSTR ExeFullPath, PULONG SizeOfImage) { ULONG Size; NTSTATUS Status; NtFileDisk file; IMAGE_DOS_HEADER DosHeader; IMAGE_NT_HEADERS NtHeader; PIMAGE_OPTIONAL_HEADER OptionalHeader; PIMAGE_SECTION_HEADER SectionHeader; Status = file.Open(ExeFullPath); if (!NT_SUCCESS(Status)) return Status; Status = file.Read(&DosHeader, sizeof(DosHeader)); if (!NT_SUCCESS(Status)) return Status; if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE) return STATUS_INVALID_IMAGE_WIN_32; Status = file.Seek(DosHeader.e_lfanew, FILE_BEGIN); if (!NT_SUCCESS(Status)) return Status; Status = file.Read(&NtHeader, sizeof(NtHeader) - sizeof(NtHeader.OptionalHeader)); if (!NT_SUCCESS(Status)) return Status; if (NtHeader.Signature != IMAGE_NT_SIGNATURE) return STATUS_INVALID_IMAGE_WIN_32; if (NtHeader.FileHeader.SizeOfOptionalHeader > FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, SizeOfImage) + RTL_FIELD_SIZE(IMAGE_OPTIONAL_HEADER, SizeOfImage)) { OptionalHeader = (PIMAGE_OPTIONAL_HEADER)AllocStack(NtHeader.FileHeader.SizeOfOptionalHeader); Status = file.Read(OptionalHeader, NtHeader.FileHeader.SizeOfOptionalHeader); if (!NT_SUCCESS(Status)) return Status; *SizeOfImage = OptionalHeader->SizeOfImage; return STATUS_SUCCESS; } SectionHeader = (PIMAGE_SECTION_HEADER)AllocStack(NtHeader.FileHeader.NumberOfSections * sizeof(*SectionHeader)); Status = file.Read(SectionHeader, NtHeader.FileHeader.NumberOfSections * sizeof(*SectionHeader)); if (!NT_SUCCESS(Status)) return Status; Size = 0; for (ULONG NumberOfSections = NtHeader.FileHeader.NumberOfSections; NumberOfSections; --NumberOfSections) { Size += SectionHeader->Misc.VirtualSize; ++SectionHeader; } Size += ROUND_UP(file.GetCurrentPos(), MEMORY_PAGE_SIZE); *SizeOfImage = Size; return STATUS_SUCCESS; }
// PENUM_BOOT_ENTRIES_ROUTINE static NTSTATUS NTAPI EnumerateInstallations( IN BOOT_STORE_TYPE Type, IN PBOOT_STORE_ENTRY BootEntry, IN PVOID Parameter OPTIONAL) { PENUM_INSTALLS_DATA Data = (PENUM_INSTALLS_DATA)Parameter; PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; PNTOS_INSTALLATION NtOsInstall; ULONG DiskNumber = 0, PartitionNumber = 0; PCWSTR PathComponent = NULL; PDISKENTRY DiskEntry = NULL; PPARTENTRY PartEntry = NULL; UNICODE_STRING SystemRootPath; WCHAR SystemRoot[MAX_PATH]; USHORT Machine; UNICODE_STRING VendorName; WCHAR VendorNameBuffer[MAX_PATH]; /* We have a boot entry */ /* Check for supported boot type "Windows2003" */ if (BootEntry->OsOptionsLength < sizeof(NTOS_OPTIONS) || RtlCompareMemory(&BootEntry->OsOptions /* Signature */, NTOS_OPTIONS_SIGNATURE, RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) != RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) { /* This is not a ReactOS entry */ // DPRINT(" An installation '%S' of unsupported type '%S'\n", // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a"); DPRINT(" An installation '%S' of unsupported type %lu\n", BootEntry->FriendlyName, BootEntry->OsOptionsLength); /* Continue the enumeration */ return STATUS_SUCCESS; } /* BootType is Windows2003, now check OsLoadPath */ if (!Options->OsLoadPath || !*Options->OsLoadPath) { /* Certainly not a ReactOS installation */ DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n", BootEntry->FriendlyName); /* Continue the enumeration */ return STATUS_SUCCESS; } DPRINT(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n", BootEntry->FriendlyName, Options->OsLoadPath); // DPRINT(" Found a Win2k3 install '%S' with ARC path '%S'\n", // BootEntry->FriendlyName, Options->OsLoadPath); // TODO: Normalize the ARC path. /* * Check whether we already have an installation with this ARC path. * If this is the case, stop there. */ NtOsInstall = FindExistingNTOSInstall(Data->List, Options->OsLoadPath, NULL); if (NtOsInstall) { DPRINT(" An NTOS installation with name \"%S\" from vendor \"%S\" already exists in SystemRoot '%wZ'\n", NtOsInstall->InstallationName, NtOsInstall->VendorName, &NtOsInstall->SystemArcPath); /* Continue the enumeration */ return STATUS_SUCCESS; } /* * Convert the ARC path into an NT path, from which we will deduce * the real disk drive & partition on which the candidate installation * resides, as well verifying whether it is indeed an NTOS installation. */ RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot)); if (!ArcPathToNtPath(&SystemRootPath, Options->OsLoadPath, Data->PartList)) { DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", Options->OsLoadPath); /* Continue the enumeration */ return STATUS_SUCCESS; } DPRINT("ArcPathToNtPath() succeeded: '%S' --> '%wZ'\n", Options->OsLoadPath, &SystemRootPath); /* * Check whether we already have an installation with this NT path. * If this is the case, stop there. */ NtOsInstall = FindExistingNTOSInstall(Data->List, NULL /*Options->OsLoadPath*/, &SystemRootPath); if (NtOsInstall) { DPRINT1(" An NTOS installation with name \"%S\" from vendor \"%S\" already exists in SystemRoot '%wZ'\n", NtOsInstall->InstallationName, NtOsInstall->VendorName, &NtOsInstall->SystemNtPath); /* Continue the enumeration */ return STATUS_SUCCESS; } DPRINT("EnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath); /* Check if this is a valid NTOS installation; stop there if it isn't one */ RtlInitEmptyUnicodeString(&VendorName, VendorNameBuffer, sizeof(VendorNameBuffer)); if (!IsValidNTOSInstallation(&SystemRootPath, &Machine, &VendorName)) { /* Continue the enumeration */ return STATUS_SUCCESS; } DPRINT("Found a valid NTOS installation in SystemRoot ARC path '%S', NT path '%wZ'\n", Options->OsLoadPath, &SystemRootPath); /* From the NT path, compute the disk, partition and path components */ if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent)) { DPRINT("SystemRootPath = '%wZ' points to disk #%d, partition #%d, path '%S'\n", &SystemRootPath, DiskNumber, PartitionNumber, PathComponent); /* Retrieve the corresponding disk and partition */ if (!GetDiskOrPartition(Data->PartList, DiskNumber, PartitionNumber, &DiskEntry, &PartEntry)) { DPRINT1("GetDiskOrPartition(disk #%d, partition #%d) failed\n", DiskNumber, PartitionNumber); } } else { DPRINT1("NtPathToDiskPartComponents(%wZ) failed\n", &SystemRootPath); } /* Add the discovered NTOS installation into the list */ AddNTOSInstallation(Data->List, BootEntry->FriendlyName, Machine, VendorName.Buffer, // FIXME: What if it's not NULL-terminated? Options->OsLoadPath, &SystemRootPath, PathComponent, DiskNumber, PartitionNumber, PartEntry); /* Continue the enumeration */ return STATUS_SUCCESS; }
*/ #include "precomp.h" typedef struct _MINIMUM_SIZE_TABLE { DWORD dwField; WORD wSize; } MINIMUM_SIZE_TABLE, *PMINIMUM_SIZE_TABLE; /** * Minimum required DEVMODEA structure size based on the used fields. Must be in descending order! */ static MINIMUM_SIZE_TABLE MinimumSizeA[] = { { DM_PANNINGHEIGHT, FIELD_OFFSET(DEVMODEA, dmPanningHeight) + RTL_FIELD_SIZE(DEVMODEA, dmPanningHeight) }, { DM_PANNINGWIDTH, FIELD_OFFSET(DEVMODEA, dmPanningWidth) + RTL_FIELD_SIZE(DEVMODEA, dmPanningWidth) }, { DM_DITHERTYPE, FIELD_OFFSET(DEVMODEA, dmDitherType) + RTL_FIELD_SIZE(DEVMODEA, dmDitherType) }, { DM_MEDIATYPE, FIELD_OFFSET(DEVMODEA, dmMediaType) + RTL_FIELD_SIZE(DEVMODEA, dmMediaType) }, { DM_ICMINTENT, FIELD_OFFSET(DEVMODEA, dmICMIntent) + RTL_FIELD_SIZE(DEVMODEA, dmICMIntent) }, { DM_ICMMETHOD, FIELD_OFFSET(DEVMODEA, dmICMMethod) + RTL_FIELD_SIZE(DEVMODEA, dmICMMethod) }, { DM_DISPLAYFREQUENCY, FIELD_OFFSET(DEVMODEA, dmDisplayFrequency) + RTL_FIELD_SIZE(DEVMODEA, dmDisplayFrequency) }, { DM_NUP, FIELD_OFFSET(DEVMODEA, dmNup) + RTL_FIELD_SIZE(DEVMODEA, dmNup) }, { DM_DISPLAYFLAGS, FIELD_OFFSET(DEVMODEA, dmDisplayFlags) + RTL_FIELD_SIZE(DEVMODEA, dmDisplayFlags) }, { DM_PELSHEIGHT, FIELD_OFFSET(DEVMODEA, dmPelsHeight) + RTL_FIELD_SIZE(DEVMODEA, dmPelsHeight) }, { DM_PELSWIDTH, FIELD_OFFSET(DEVMODEA, dmPelsWidth) + RTL_FIELD_SIZE(DEVMODEA, dmPelsWidth) }, { DM_BITSPERPEL, FIELD_OFFSET(DEVMODEA, dmBitsPerPel) + RTL_FIELD_SIZE(DEVMODEA, dmBitsPerPel) }, { DM_LOGPIXELS, FIELD_OFFSET(DEVMODEA, dmLogPixels) + RTL_FIELD_SIZE(DEVMODEA, dmLogPixels) }, { DM_FORMNAME, FIELD_OFFSET(DEVMODEA, dmFormName) + RTL_FIELD_SIZE(DEVMODEA, dmFormName) }, { DM_COLLATE, FIELD_OFFSET(DEVMODEA, dmCollate) + RTL_FIELD_SIZE(DEVMODEA, dmCollate) }, { DM_TTOPTION, FIELD_OFFSET(DEVMODEA, dmTTOption) + RTL_FIELD_SIZE(DEVMODEA, dmTTOption) },
DWORD WINAPI DECLSPEC_HOTPATCH GetAdaptersAddresses( _In_ ULONG Family, _In_ ULONG Flags, _In_ PVOID Reserved, _Inout_ PIP_ADAPTER_ADDRESSES pAdapterAddresses, _Inout_ PULONG pOutBufLen) { NTSTATUS Status; HANDLE TcpFile; TDIEntityID* InterfacesList; ULONG InterfacesCount; ULONG AdaptersCount = 0; ULONG i; ULONG TotalSize = 0, RemainingSize; BYTE* Ptr = (BYTE*)pAdapterAddresses; DWORD MIN_SIZE = 15 * 1024; PIP_ADAPTER_ADDRESSES PreviousAA = NULL; FIXME("GetAdaptersAddresses - Semi Stub: Family %u, Flags 0x%08x, Reserved %p, pAdapterAddress %p, pOutBufLen %p.\n", Family, Flags, Reserved, pAdapterAddresses, pOutBufLen); if (!pOutBufLen) return ERROR_INVALID_PARAMETER; // FIXME: the exact needed size should be computed first, BEFORE doing any write to the output buffer. // As suggested by MSDN, require a 15 KB buffer, which allows to React properly to length checks. if(!Ptr || *pOutBufLen < MIN_SIZE) { *pOutBufLen = MIN_SIZE; return ERROR_BUFFER_OVERFLOW; } switch(Family) { case AF_INET: break; case AF_INET6: /* One day maybe... */ FIXME("IPv6 is not supported in ReactOS!\n"); /* We got nothing to say in this case */ return ERROR_NO_DATA; break; case AF_UNSPEC: WARN("IPv6 addresses ignored, IPv4 only\n"); Family = AF_INET; break; default: ERR("Invalid family 0x%x\n", Family); return ERROR_INVALID_PARAMETER; break; } RemainingSize = *pOutBufLen; if (Ptr) ZeroMemory(Ptr, RemainingSize); /* open the tcpip driver */ Status = openTcpFile(&TcpFile, FILE_READ_DATA); if (!NT_SUCCESS(Status)) { ERR("Could not open handle to tcpip.sys. Status %08x\n", Status); return RtlNtStatusToDosError(Status); } /* Get the interfaces list */ Status = GetInterfacesList(TcpFile, &InterfacesList, &InterfacesCount); if (!NT_SUCCESS(Status)) { ERR("Could not get adapters list. Status %08x\n", Status); NtClose(TcpFile); return RtlNtStatusToDosError(Status); } /* Let's see if we got any adapter. */ for (i = 0; i < InterfacesCount; i++) { PIP_ADAPTER_ADDRESSES CurrentAA = (PIP_ADAPTER_ADDRESSES)Ptr; ULONG CurrentAASize = 0; if (InterfacesList[i].tei_entity == IF_ENTITY) { BYTE EntryBuffer[FIELD_OFFSET(IFEntry, if_descr) + RTL_FIELD_SIZE(IFEntry, if_descr[0]) * (MAX_ADAPTER_DESCRIPTION_LENGTH + 1)]; IFEntry* Entry = (IFEntry*)EntryBuffer; /* Remember we got one */ AdaptersCount++; /* Set the pointer to this instance in the previous one*/ if(PreviousAA) PreviousAA->Next = CurrentAA; /* Of course we need some space for the base structure. */ CurrentAASize = sizeof(IP_ADAPTER_ADDRESSES); /* Get the entry */ Status = GetInterfaceEntry(TcpFile, InterfacesList[i], Entry); if (!NT_SUCCESS(Status)) goto Error; TRACE("Got entity %*s, index %u.\n", Entry->if_descrlen, &Entry->if_descr[0], Entry->if_index); /* Add the adapter name */ CurrentAASize += Entry->if_descrlen + sizeof(CHAR); /* Add the DNS suffix */ CurrentAASize += sizeof(WCHAR); /* Add the description. */ CurrentAASize += sizeof(WCHAR); if (!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME)) { /* Just an empty string for now. */ FIXME("Should get adapter friendly name.\n"); CurrentAASize += sizeof(WCHAR); } if (!(Flags & GAA_FLAG_SKIP_DNS_SERVER)) { /* Enumerate the name servers */ HKEY InterfaceKey; CHAR KeyName[256]; snprintf(KeyName, 256, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%*s", Entry->if_descrlen, &Entry->if_descr[0]); if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &InterfaceKey) != ERROR_SUCCESS) { ERR("Failed opening interface key for interface %*s\n", Entry->if_descrlen, &Entry->if_descr[0]); Flags |= GAA_FLAG_SKIP_DNS_SERVER; } else { EnumNameServers(InterfaceKey, NULL, &CurrentAASize, EnumerateServerNameSize); RegCloseKey(InterfaceKey); } } /* This is part of what we will need */ TotalSize += CurrentAASize; /* Fill in the data */ if ((CurrentAA) && (RemainingSize >= CurrentAASize)) { CurrentAA->Length = sizeof(IP_ADAPTER_ADDRESSES); CurrentAA->IfIndex = Entry->if_index; CopyMemory(CurrentAA->PhysicalAddress, Entry->if_physaddr, Entry->if_physaddrlen); CurrentAA->PhysicalAddressLength = Entry->if_physaddrlen; CurrentAA->Flags = 0; // FIXME! CurrentAA->Mtu = Entry->if_mtu; CurrentAA->IfType = Entry->if_type; CurrentAA->OperStatus = Entry->if_operstatus; /* Next items */ Ptr = (BYTE*)(CurrentAA + 1); /* Now fill in the name */ CopyMemory(Ptr, &Entry->if_descr[0], Entry->if_descrlen); CurrentAA->AdapterName = (PCHAR)Ptr; CurrentAA->AdapterName[Entry->if_descrlen] = '\0'; /* Next items */ Ptr = (BYTE*)(CurrentAA->AdapterName + Entry->if_descrlen + 1); /* The DNS suffix */ CurrentAA->DnsSuffix = (PWCHAR)Ptr; CurrentAA->DnsSuffix[0] = L'\0'; /* Next items */ Ptr = (BYTE*)(CurrentAA->DnsSuffix + 1); /* The description */ CurrentAA->Description = (PWCHAR)Ptr; CurrentAA->Description[0] = L'\0'; /* Next items */ Ptr = (BYTE*)(CurrentAA->Description + 1); /* The friendly name */ if (!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME)) { CurrentAA->FriendlyName = (PWCHAR)Ptr; CurrentAA->FriendlyName[0] = L'\0'; /* Next items */ Ptr = (BYTE*)(CurrentAA->FriendlyName + 1); } /* The DNS Servers */ if (!(Flags & GAA_FLAG_SKIP_DNS_SERVER)) { /* Enumerate the name servers */ HKEY InterfaceKey; CHAR KeyName[256]; snprintf(KeyName, 256, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%*s", Entry->if_descrlen, &Entry->if_descr[0]); if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &InterfaceKey) != ERROR_SUCCESS) { ERR("Failed opening interface key for interface %*s\n", Entry->if_descrlen, &Entry->if_descr[0]); } else { PIP_ADAPTER_DNS_SERVER_ADDRESS* ServerAddressPtr; CurrentAA->FirstDnsServerAddress = (PIP_ADAPTER_DNS_SERVER_ADDRESS)Ptr; ServerAddressPtr = &CurrentAA->FirstDnsServerAddress; EnumNameServers(InterfaceKey, NULL, &ServerAddressPtr, EnumerateServerName); RegCloseKey(InterfaceKey); /* Set the last entry in the list as having NULL next member */ Ptr = (BYTE*)*ServerAddressPtr; *ServerAddressPtr = NULL; } } /* We're done for this interface */ PreviousAA = CurrentAA; RemainingSize -= CurrentAASize; } } } if (AdaptersCount == 0) { /* Uh? Not even localhost ?! */ ERR("No Adapters found!\n"); *pOutBufLen = 0; return ERROR_NO_DATA; } /* See if we have anything to add */ // FIXME: Anycast and multicast if ((Flags & (GAA_FLAG_SKIP_UNICAST | GAA_FLAG_INCLUDE_PREFIX)) == GAA_FLAG_SKIP_UNICAST) goto Success; /* Now fill in the addresses */ for (i = 0; i < InterfacesCount; i++) { /* Look for network layers */ if ((InterfacesList[i].tei_entity == CL_NL_ENTITY) || (InterfacesList[i].tei_entity == CO_NL_ENTITY)) { IPSNMPInfo SnmpInfo; PIP_ADAPTER_ADDRESSES CurrentAA = NULL; IPAddrEntry* AddrEntries; ULONG j; /* Get its SNMP info */ Status = GetSnmpInfo(TcpFile, InterfacesList[i], &SnmpInfo); if (!NT_SUCCESS(Status)) goto Error; if (SnmpInfo.ipsi_numaddr == 0) continue; /* Allocate the address entry array and get them */ AddrEntries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SnmpInfo.ipsi_numaddr * sizeof(AddrEntries[0])); if (!AddrEntries) { Status = STATUS_NO_MEMORY; goto Error; } Status = GetAddrEntries(TcpFile, InterfacesList[i], AddrEntries, SnmpInfo.ipsi_numaddr); if (!NT_SUCCESS(Status)) { HeapFree(GetProcessHeap(), 0, AddrEntries); goto Error; } for (j = 0; j < SnmpInfo.ipsi_numaddr; j++) { /* Find the adapters struct for this address. */ if (pAdapterAddresses) { CurrentAA = pAdapterAddresses; while (CurrentAA) { if (CurrentAA->IfIndex == AddrEntries[j].iae_index) break; CurrentAA = CurrentAA->Next; } if (!CurrentAA) { ERR("Got address for interface %u but no adapter was found for it.\n", AddrEntries[j].iae_index); /* Go to the next address */ continue; } } ERR("address is 0x%08x, mask is 0x%08x\n", AddrEntries[j].iae_addr, AddrEntries[j].iae_mask); //FIXME: For now reactos only supports unicast addresses if (!(Flags & GAA_FLAG_SKIP_UNICAST)) { ULONG Size = sizeof(IP_ADAPTER_UNICAST_ADDRESS) + sizeof(SOCKADDR); if (Ptr && (RemainingSize >= Size)) { PIP_ADAPTER_UNICAST_ADDRESS UnicastAddress = (PIP_ADAPTER_UNICAST_ADDRESS)Ptr; /* Fill in the structure */ UnicastAddress->Length = sizeof(IP_ADAPTER_UNICAST_ADDRESS); UnicastAddress->Next = CurrentAA->FirstUnicastAddress; // FIXME: Put meaningful value here UnicastAddress->Flags = 0; UnicastAddress->PrefixOrigin = IpPrefixOriginOther; UnicastAddress->SuffixOrigin = IpSuffixOriginOther; UnicastAddress->DadState = IpDadStatePreferred; UnicastAddress->ValidLifetime = 0xFFFFFFFF; UnicastAddress->PreferredLifetime = 0xFFFFFFFF; /* Set the address */ //FIXME: ipv4 only (again...) UnicastAddress->Address.lpSockaddr = (LPSOCKADDR)(UnicastAddress + 1); UnicastAddress->Address.iSockaddrLength = sizeof(AddrEntries[j].iae_addr); UnicastAddress->Address.lpSockaddr->sa_family = AF_INET; memcpy(UnicastAddress->Address.lpSockaddr->sa_data, &AddrEntries[j].iae_addr, sizeof(AddrEntries[j].iae_addr)); CurrentAA->FirstUnicastAddress = UnicastAddress; Ptr += Size; RemainingSize -= Size; } TotalSize += Size; } if (Flags & GAA_FLAG_INCLUDE_PREFIX) { ULONG Size = sizeof(IP_ADAPTER_PREFIX) + sizeof(SOCKADDR); if (Ptr && (RemainingSize >= Size)) { PIP_ADAPTER_PREFIX Prefix = (PIP_ADAPTER_PREFIX)Ptr; /* Fill in the structure */ Prefix->Length = sizeof(IP_ADAPTER_PREFIX); Prefix->Next = CurrentAA->FirstPrefix; /* Set the address */ //FIXME: ipv4 only (again...) Prefix->Address.lpSockaddr = (LPSOCKADDR)(Prefix + 1); Prefix->Address.iSockaddrLength = sizeof(AddrEntries[j].iae_mask); Prefix->Address.lpSockaddr->sa_family = AF_INET; memcpy(Prefix->Address.lpSockaddr->sa_data, &AddrEntries[j].iae_mask, sizeof(AddrEntries[j].iae_mask)); /* Compute the prefix size */ _BitScanReverse(&Prefix->PrefixLength, AddrEntries[j].iae_mask); CurrentAA->FirstPrefix = Prefix; Ptr += Size; RemainingSize -= Size; } TotalSize += Size; } } HeapFree(GetProcessHeap(), 0, AddrEntries); } } Success: /* We're done */ HeapFree(GetProcessHeap(), 0, InterfacesList); NtClose(TcpFile); *pOutBufLen = TotalSize; TRACE("TotalSize: %x\n", *pOutBufLen); return ERROR_SUCCESS; Error: ERR("Failed! Status 0x%08x\n", Status); *pOutBufLen = 0; HeapFree(GetProcessHeap(), 0, InterfacesList); NtClose(TcpFile); return RtlNtStatusToDosError(Status); }