ReactOS  0.4.11-dev-791-gf6f1255
osdetect.c File Reference
#include "precomp.h"
#include "ntverrsrc.h"
#include "bldrsup.h"
#include "filesup.h"
#include "genlist.h"
#include "partlist.h"
#include "arcname.h"
#include "osdetect.h"
#include <debug.h>
Include dependency graph for osdetect.c:

Go to the source code of this file.

Classes

struct  _ENUM_INSTALLS_DATA
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _ENUM_INSTALLS_DATA ENUM_INSTALLS_DATA
 
typedef struct
_ENUM_INSTALLS_DATA
PENUM_INSTALLS_DATA
 

Functions

static BOOLEAN IsValidNTOSInstallation (IN PUNICODE_STRING SystemRootPath, OUT PUSHORT Machine OPTIONAL, OUT PUNICODE_STRING VendorName OPTIONAL)
 
static PNTOS_INSTALLATION FindExistingNTOSInstall (IN PGENERIC_LIST List, IN PCWSTR SystemRootArcPath OPTIONAL, IN PUNICODE_STRING SystemRootNtPath OPTIONAL)
 
static PNTOS_INSTALLATION AddNTOSInstallation (IN PGENERIC_LIST List, IN PCWSTR InstallationName, IN USHORT Machine, IN PCWSTR VendorName, IN PCWSTR SystemRootArcPath, IN PUNICODE_STRING SystemRootNtPath, IN PCWSTR PathComponent, IN ULONG DiskNumber, IN ULONG PartitionNumber, IN PPARTENTRY PartEntry OPTIONAL)
 
static NTSTATUS NTAPI EnumerateInstallations (IN BOOT_STORE_TYPE Type, IN PBOOT_STORE_ENTRY BootEntry, IN PVOID Parameter OPTIONAL)
 
PCWSTR FindSubStrI (PCWSTR str, PCWSTR strSearch)
 
static BOOLEAN CheckForValidPEAndVendor (IN HANDLE RootDirectory OPTIONAL, IN PCWSTR PathNameToFile, OUT PUSHORT Machine, OUT PUNICODE_STRING VendorName)
 
static BOOLEAN IsValidNTOSInstallationByHandle (IN HANDLE SystemRootDirectory, OUT PUSHORT Machine OPTIONAL, OUT PUNICODE_STRING VendorName OPTIONAL)
 
static VOID FindNTOSInstallations (IN OUT PGENERIC_LIST List, IN PPARTLIST PartList, IN PPARTENTRY PartEntry)
 
FORCEINLINE BOOLEAN ShouldICheckThisPartition (IN PPARTENTRY PartEntry)
 
PGENERIC_LIST CreateNTOSInstallationsList (IN PPARTLIST PartList)
 

Variables

static const PCWSTR KnownVendors [] = { VENDOR_REACTOS, VENDOR_MICROSOFT }
 

Macro Definition Documentation

#define NDEBUG

Definition at line 22 of file osdetect.c.

Typedef Documentation

Function Documentation

static PNTOS_INSTALLATION AddNTOSInstallation ( IN PGENERIC_LIST  List,
IN PCWSTR  InstallationName,
IN USHORT  Machine,
IN PCWSTR  VendorName,
IN PCWSTR  SystemRootArcPath,
IN PUNICODE_STRING  SystemRootNtPath,
IN PCWSTR  PathComponent,
IN ULONG  DiskNumber,
IN ULONG  PartitionNumber,
IN PPARTENTRY PartEntry  OPTIONAL 
)
static

Definition at line 609 of file osdetect.c.

Referenced by EnumerateInstallations().

620 {
621  PNTOS_INSTALLATION NtOsInstall;
622  SIZE_T ArcPathLength, NtPathLength;
623 
624  /* Is there already any installation with these settings? */
625  NtOsInstall = FindExistingNTOSInstall(List, SystemRootArcPath, SystemRootNtPath);
626  if (NtOsInstall)
627  {
628  DPRINT1("An NTOS installation with name \"%S\" from vendor \"%S\" already exists on disk #%d, partition #%d, in SystemRoot '%wZ'\n",
629  NtOsInstall->InstallationName, NtOsInstall->VendorName,
630  NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber, &NtOsInstall->SystemNtPath);
631  //
632  // NOTE: We may use its "IsDefault" attribute, and only keep the entries that have IsDefault == TRUE...
633  // Setting IsDefault to TRUE would imply searching for the "Default" entry in the loader configuration file.
634  //
635  return NtOsInstall;
636  }
637 
638  ArcPathLength = (wcslen(SystemRootArcPath) + 1) * sizeof(WCHAR);
639  // NtPathLength = ROUND_UP(SystemRootNtPath->Length + sizeof(UNICODE_NULL), sizeof(WCHAR));
640  NtPathLength = SystemRootNtPath->Length + sizeof(UNICODE_NULL);
641 
642  /* None was found, so add a new one */
644  sizeof(*NtOsInstall) +
645  ArcPathLength + NtPathLength);
646  if (!NtOsInstall)
647  return NULL;
648 
649  NtOsInstall->DiskNumber = DiskNumber;
650  NtOsInstall->PartitionNumber = PartitionNumber;
651  NtOsInstall->PartEntry = PartEntry;
652 
653  NtOsInstall->Machine = Machine;
654 
655  RtlInitEmptyUnicodeString(&NtOsInstall->SystemArcPath,
656  (PWCHAR)(NtOsInstall + 1),
657  ArcPathLength);
658  RtlCopyMemory(NtOsInstall->SystemArcPath.Buffer, SystemRootArcPath, ArcPathLength);
659  NtOsInstall->SystemArcPath.Length = ArcPathLength - sizeof(UNICODE_NULL);
660 
661  RtlInitEmptyUnicodeString(&NtOsInstall->SystemNtPath,
662  (PWCHAR)((ULONG_PTR)(NtOsInstall + 1) + ArcPathLength),
663  NtPathLength);
664  RtlCopyUnicodeString(&NtOsInstall->SystemNtPath, SystemRootNtPath);
665  NtOsInstall->PathComponent = NtOsInstall->SystemNtPath.Buffer +
666  (PathComponent - SystemRootNtPath->Buffer);
667 
668  RtlStringCchCopyW(NtOsInstall->InstallationName,
669  ARRAYSIZE(NtOsInstall->InstallationName),
670  InstallationName);
671 
672  RtlStringCchCopyW(NtOsInstall->VendorName,
673  ARRAYSIZE(NtOsInstall->VendorName),
674  VendorName);
675 
676  AppendGenericListEntry(List, NtOsInstall, FALSE);
677 
678  return NtOsInstall;
679 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR VendorName[MAX_PATH]
Definition: osdetect.h:27
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
uint16_t * PWCHAR
Definition: typedefs.h:54
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2056
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
PPARTENTRY PartEntry
Definition: osdetect.h:25
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
LIST_ENTRY List
Definition: psmgr.c:57
WCHAR InstallationName[MAX_PATH]
Definition: osdetect.h:26
static PNTOS_INSTALLATION FindExistingNTOSInstall(IN PGENERIC_LIST List, IN PCWSTR SystemRootArcPath OPTIONAL, IN PUNICODE_STRING SystemRootNtPath OPTIONAL)
Definition: osdetect.c:565
BOOLEAN AppendGenericListEntry(IN OUT PGENERIC_LIST List, IN PVOID Data, IN BOOLEAN Current)
Definition: genlist.c:62
HANDLE ProcessHeap
Definition: servman.c:15
ULONG_PTR SIZE_T
Definition: typedefs.h:78
PCWSTR PathComponent
Definition: osdetect.h:22
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:135
UNICODE_STRING SystemArcPath
Definition: osdetect.h:20
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
ULONG PartitionNumber
Definition: osdetect.h:24
#define DPRINT1
Definition: precomp.h:8
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
UNICODE_STRING SystemNtPath
Definition: osdetect.h:21
static BOOLEAN CheckForValidPEAndVendor ( IN HANDLE RootDirectory  OPTIONAL,
IN PCWSTR  PathNameToFile,
OUT PUSHORT  Machine,
OUT PUNICODE_STRING  VendorName 
)
static

Definition at line 243 of file osdetect.c.

Referenced by IsValidNTOSInstallationByHandle().

248 {
251  HANDLE FileHandle, SectionHandle;
252  // SIZE_T ViewSize;
253  PVOID ViewBase;
254  PIMAGE_NT_HEADERS NtHeader;
255  PVOID VersionBuffer = NULL; // Read-only
256  PVOID pvData = NULL;
257  UINT BufLen = 0;
258 
259  if (VendorName->MaximumLength < sizeof(UNICODE_NULL))
260  return FALSE;
261 
262  *VendorName->Buffer = UNICODE_NULL;
263  VendorName->Length = 0;
264 
265  Status = OpenAndMapFile(RootDirectory, PathNameToFile,
266  &FileHandle, &SectionHandle, &ViewBase,
267  NULL, FALSE);
268  if (!NT_SUCCESS(Status))
269  {
270  DPRINT1("Failed to open and map file '%S', Status 0x%08lx\n", PathNameToFile, Status);
271  return FALSE; // Status;
272  }
273 
274  /* Make sure it's a valid NT PE file */
275  NtHeader = RtlImageNtHeader(ViewBase);
276  if (!NtHeader)
277  {
278  DPRINT1("File '%S' does not seem to be a valid NT PE file, bail out\n", PathNameToFile);
280  goto UnmapCloseFile;
281  }
282 
283  /* Retrieve the target architecture of this PE module */
284  *Machine = NtHeader->FileHeader.Machine;
285 
286  /*
287  * Search for a valid executable version and vendor.
288  * NOTE: The module is loaded as a data file, it should be marked as such.
289  */
290  Status = NtGetVersionResource((PVOID)((ULONG_PTR)ViewBase | 1), &VersionBuffer, NULL);
291  if (!NT_SUCCESS(Status))
292  {
293  DPRINT1("Failed to get version resource for file '%S', Status 0x%08lx\n", PathNameToFile, Status);
294  goto UnmapCloseFile;
295  }
296 
297  Status = NtVerQueryValue(VersionBuffer, L"\\VarFileInfo\\Translation", &pvData, &BufLen);
298  if (NT_SUCCESS(Status))
299  {
300  USHORT wCodePage = 0, wLangID = 0;
302 
303  wCodePage = LOWORD(*(ULONG*)pvData);
304  wLangID = HIWORD(*(ULONG*)pvData);
305 
306  RtlStringCchPrintfW(FileInfo, ARRAYSIZE(FileInfo),
307  L"StringFileInfo\\%04X%04X\\CompanyName",
308  wCodePage, wLangID);
309 
310  Status = NtVerQueryValue(VersionBuffer, FileInfo, &pvData, &BufLen);
311 
312  /* Fixup the Status in case pvData is NULL */
313  if (NT_SUCCESS(Status) && !pvData)
314  Status = STATUS_NOT_FOUND;
315 
316  if (NT_SUCCESS(Status) /*&& pvData*/)
317  {
318  /* BufLen includes the NULL terminator count */
319  DPRINT("Found version vendor: \"%S\" for file '%S'\n", pvData, PathNameToFile);
320 
321  RtlStringCbCopyNW(VendorName->Buffer, VendorName->MaximumLength,
322  pvData, BufLen * sizeof(WCHAR));
323  VendorName->Length = wcslen(VendorName->Buffer) * sizeof(WCHAR);
324 
325  Success = TRUE;
326  }
327  }
328 
329  if (!NT_SUCCESS(Status))
330  DPRINT("No version vendor found for file '%S'\n", PathNameToFile);
331 
332 UnmapCloseFile:
333  /* Finally, unmap and close the file */
334  UnMapAndCloseFile(FileHandle, SectionHandle, ViewBase);
335 
336  return Success;
337 }
DWORD *typedef PVOID
Definition: winlogon.h:61
#define TRUE
Definition: types.h:120
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
#define BufLen
Definition: fatfs.h:167
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define WCHAR
Definition: msvc.h:43
NTSTATUS NtVerQueryValue(IN const VOID *pBlock, IN PCWSTR lpSubBlock, OUT PVOID *lplpBuffer, OUT PUINT puLen)
Definition: ntverrsrc.c:174
uint32_t ULONG_PTR
Definition: typedefs.h:63
HANDLE FileHandle
Definition: stats.c:38
NTSTATUS NtGetVersionResource(IN PVOID BaseAddress, OUT PVOID *Resource, OUT PULONG ResourceSize OPTIONAL)
Definition: ntverrsrc.c:26
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
NTSTRSAFEAPI RtlStringCbCopyNW(_Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc, _In_ size_t cbToCopy)
Definition: ntstrsafe.h:411
_In_ ULONG _In_opt_ PVOID pvData
Definition: winddi.h:3748
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
static __inline NTSTATUS RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1064
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
unsigned char BOOLEAN
#define STATUS_NOT_FOUND
Definition: shellext.h:55
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:345
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define MAX_PATH
Definition: compat.h:26
static const WCHAR L[]
Definition: oid.c:1087
Status
Definition: gdiplustypes.h:24
DWORD *typedef HANDLE
Definition: winlogon.h:61
#define UnMapAndCloseFile(FileHandle, SectionHandle, BaseAddress)
Definition: filesup.h:108
unsigned short USHORT
Definition: pedump.c:61
unsigned int UINT
Definition: ndis.h:50
#define DPRINT1
Definition: precomp.h:8
#define RtlImageNtHeader
Definition: compat.h:457
#define HIWORD(l)
Definition: typedefs.h:246
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS OpenAndMapFile(IN HANDLE RootDirectory OPTIONAL, IN PCWSTR PathNameToFile, OUT PHANDLE FileHandle, OUT PHANDLE SectionHandle, OUT PVOID *BaseAddress, OUT PULONG FileSize OPTIONAL, IN BOOLEAN ReadWriteAccess)
Definition: filesup.c:858
#define LOWORD(l)
Definition: pedump.c:82
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PGENERIC_LIST CreateNTOSInstallationsList ( IN PPARTLIST  PartList)

Definition at line 775 of file osdetect.c.

Referenced by LoadSetupData(), and UpgradeRepairPage().

777 {
779  PLIST_ENTRY Entry, Entry2;
780  PDISKENTRY DiskEntry;
781  PPARTENTRY PartEntry;
782 
783  List = CreateGenericList();
784  if (List == NULL)
785  return NULL;
786 
787  /* Loop each available disk ... */
788  Entry = PartList->DiskListHead.Flink;
789  while (Entry != &PartList->DiskListHead)
790  {
791  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
792  Entry = Entry->Flink;
793 
794  DPRINT("Disk #%d\n", DiskEntry->DiskNumber);
795 
796  /* ... and for each disk, loop each available partition */
797 
798  /* First, the primary partitions */
799  Entry2 = DiskEntry->PrimaryPartListHead.Flink;
800  while (Entry2 != &DiskEntry->PrimaryPartListHead)
801  {
802  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
803  Entry2 = Entry2->Flink;
804 
805  ASSERT(PartEntry->DiskEntry == DiskEntry);
806 
807  DPRINT(" Primary Partition #%d, index %d - Type 0x%02x, IsLogical = %s, IsPartitioned = %s, IsNew = %s, AutoCreate = %s, FormatState = %lu -- Should I check it? %s\n",
808  PartEntry->PartitionNumber, PartEntry->PartitionIndex,
809  PartEntry->PartitionType, PartEntry->LogicalPartition ? "TRUE" : "FALSE",
810  PartEntry->IsPartitioned ? "TRUE" : "FALSE",
811  PartEntry->New ? "Yes" : "No",
812  PartEntry->AutoCreate ? "Yes" : "No",
813  PartEntry->FormatState,
814  ShouldICheckThisPartition(PartEntry) ? "YES!" : "NO!");
815 
816  if (ShouldICheckThisPartition(PartEntry))
817  FindNTOSInstallations(List, PartList, PartEntry);
818  }
819 
820  /* Then, the logical partitions (present in the extended partition) */
821  Entry2 = DiskEntry->LogicalPartListHead.Flink;
822  while (Entry2 != &DiskEntry->LogicalPartListHead)
823  {
824  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
825  Entry2 = Entry2->Flink;
826 
827  ASSERT(PartEntry->DiskEntry == DiskEntry);
828 
829  DPRINT(" Logical Partition #%d, index %d - Type 0x%02x, IsLogical = %s, IsPartitioned = %s, IsNew = %s, AutoCreate = %s, FormatState = %lu -- Should I check it? %s\n",
830  PartEntry->PartitionNumber, PartEntry->PartitionIndex,
831  PartEntry->PartitionType, PartEntry->LogicalPartition ? "TRUE" : "FALSE",
832  PartEntry->IsPartitioned ? "TRUE" : "FALSE",
833  PartEntry->New ? "Yes" : "No",
834  PartEntry->AutoCreate ? "Yes" : "No",
835  PartEntry->FormatState,
836  ShouldICheckThisPartition(PartEntry) ? "YES!" : "NO!");
837 
838  if (ShouldICheckThisPartition(PartEntry))
839  FindNTOSInstallations(List, PartList, PartEntry);
840  }
841  }
842 
843 #ifndef NDEBUG
844  /**** Debugging: List all the collected installations ****/
845  DumpNTOSInstalls(List);
846 #endif
847 
848  return List;
849 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:133
ULONG PartitionNumber
Definition: partlist.h:49
struct _Entry Entry
Definition: kefuncs.h:640
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
ULONG DiskNumber
Definition: partlist.h:110
static VOID FindNTOSInstallations(IN OUT PGENERIC_LIST List, IN PPARTLIST PartList, IN PPARTENTRY PartEntry)
Definition: osdetect.c:682
BOOLEAN LogicalPartition
Definition: partlist.h:56
FORMATSTATE FormatState
Definition: partlist.h:70
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
BOOLEAN AutoCreate
Definition: partlist.h:65
PGENERIC_LIST CreateGenericList(VOID)
Definition: genlist.c:20
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
UCHAR PartitionType
Definition: partlist.h:47
struct _DISKENTRY * DiskEntry
Definition: partlist.h:40
LIST_ENTRY List
Definition: psmgr.c:57
Definition: typedefs.h:117
BOOLEAN New
Definition: partlist.h:62
FORCEINLINE BOOLEAN ShouldICheckThisPartition(IN PPARTENTRY PartEntry)
Definition: osdetect.c:761
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:134
BOOLEAN IsPartitioned
Definition: partlist.h:59
ULONG PartitionIndex
Definition: partlist.h:50
static NTSTATUS NTAPI EnumerateInstallations ( IN BOOT_STORE_TYPE  Type,
IN PBOOT_STORE_ENTRY  BootEntry,
IN PVOID Parameter  OPTIONAL 
)
static

Definition at line 70 of file osdetect.c.

Referenced by FindNTOSInstallations().

74 {
76  PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
77  PNTOS_INSTALLATION NtOsInstall;
78 
79  ULONG DiskNumber = 0, PartitionNumber = 0;
81  PDISKENTRY DiskEntry = NULL;
82  PPARTENTRY PartEntry = NULL;
83 
84  UNICODE_STRING SystemRootPath;
86 
87  USHORT Machine;
88  UNICODE_STRING VendorName;
89  WCHAR VendorNameBuffer[MAX_PATH];
90 
91 
92  /* We have a boot entry */
93 
94  /* Check for supported boot type "Windows2003" */
95  if (BootEntry->OsOptionsLength < sizeof(NTOS_OPTIONS) ||
96  RtlCompareMemory(&BootEntry->OsOptions /* Signature */,
100  {
101  /* This is not a ReactOS entry */
102  // DPRINT(" An installation '%S' of unsupported type '%S'\n",
103  // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a");
104  DPRINT(" An installation '%S' of unsupported type %lu\n",
105  BootEntry->FriendlyName, BootEntry->OsOptionsLength);
106  /* Continue the enumeration */
107  return STATUS_SUCCESS;
108  }
109 
110  /* BootType is Windows2003, now check OsLoadPath */
111  if (!Options->OsLoadPath || !*Options->OsLoadPath)
112  {
113  /* Certainly not a ReactOS installation */
114  DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n", BootEntry->FriendlyName);
115  /* Continue the enumeration */
116  return STATUS_SUCCESS;
117  }
118 
119  DPRINT(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n",
120  BootEntry->FriendlyName, Options->OsLoadPath);
121  // DPRINT(" Found a Win2k3 install '%S' with ARC path '%S'\n",
122  // BootEntry->FriendlyName, Options->OsLoadPath);
123 
124  // TODO: Normalize the ARC path.
125 
126  /*
127  * Check whether we already have an installation with this ARC path.
128  * If this is the case, stop there.
129  */
130  NtOsInstall = FindExistingNTOSInstall(Data->List, Options->OsLoadPath, NULL);
131  if (NtOsInstall)
132  {
133  DPRINT(" An NTOS installation with name \"%S\" from vendor \"%S\" already exists in SystemRoot '%wZ'\n",
134  NtOsInstall->InstallationName, NtOsInstall->VendorName, &NtOsInstall->SystemArcPath);
135  /* Continue the enumeration */
136  return STATUS_SUCCESS;
137  }
138 
139  /*
140  * Convert the ARC path into an NT path, from which we will deduce
141  * the real disk drive & partition on which the candidate installation
142  * resides, as well verifying whether it is indeed an NTOS installation.
143  */
144  RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
145  if (!ArcPathToNtPath(&SystemRootPath, Options->OsLoadPath, Data->PartList))
146  {
147  DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", Options->OsLoadPath);
148  /* Continue the enumeration */
149  return STATUS_SUCCESS;
150  }
151 
152  DPRINT("ArcPathToNtPath() succeeded: '%S' --> '%wZ'\n",
153  Options->OsLoadPath, &SystemRootPath);
154 
155  /*
156  * Check whether we already have an installation with this NT path.
157  * If this is the case, stop there.
158  */
159  NtOsInstall = FindExistingNTOSInstall(Data->List, NULL /*Options->OsLoadPath*/, &SystemRootPath);
160  if (NtOsInstall)
161  {
162  DPRINT1(" An NTOS installation with name \"%S\" from vendor \"%S\" already exists in SystemRoot '%wZ'\n",
163  NtOsInstall->InstallationName, NtOsInstall->VendorName, &NtOsInstall->SystemNtPath);
164  /* Continue the enumeration */
165  return STATUS_SUCCESS;
166  }
167 
168  DPRINT("EnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath);
169 
170  /* Check if this is a valid NTOS installation; stop there if it isn't one */
171  RtlInitEmptyUnicodeString(&VendorName, VendorNameBuffer, sizeof(VendorNameBuffer));
172  if (!IsValidNTOSInstallation(&SystemRootPath, &Machine, &VendorName))
173  {
174  /* Continue the enumeration */
175  return STATUS_SUCCESS;
176  }
177 
178  DPRINT("Found a valid NTOS installation in SystemRoot ARC path '%S', NT path '%wZ'\n",
179  Options->OsLoadPath, &SystemRootPath);
180 
181  /* From the NT path, compute the disk, partition and path components */
182  if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
183  {
184  DPRINT("SystemRootPath = '%wZ' points to disk #%d, partition #%d, path '%S'\n",
185  &SystemRootPath, DiskNumber, PartitionNumber, PathComponent);
186 
187  /* Retrieve the corresponding disk and partition */
188  if (!GetDiskOrPartition(Data->PartList, DiskNumber, PartitionNumber, &DiskEntry, &PartEntry))
189  {
190  DPRINT1("GetDiskOrPartition(disk #%d, partition #%d) failed\n",
191  DiskNumber, PartitionNumber);
192  }
193  }
194  else
195  {
196  DPRINT1("NtPathToDiskPartComponents(%wZ) failed\n", &SystemRootPath);
197  }
198 
199  /* Add the discovered NTOS installation into the list */
201  BootEntry->FriendlyName,
202  Machine,
203  VendorName.Buffer, // FIXME: What if it's not NULL-terminated?
204  Options->OsLoadPath,
205  &SystemRootPath, PathComponent,
206  DiskNumber, PartitionNumber, PartEntry);
207 
208  /* Continue the enumeration */
209  return STATUS_SUCCESS;
210 }
#define NTOS_OPTIONS_SIGNATURE
Definition: bldrsup.h:98
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:84
static BOOLEAN IsValidNTOSInstallation(IN PUNICODE_STRING SystemRootPath, OUT PUSHORT Machine OPTIONAL, OUT PUNICODE_STRING VendorName OPTIONAL)
Definition: osdetect.c:500
__wchar_t WCHAR
Definition: xmlstorage.h:180
BOOLEAN ArcPathToNtPath(OUT PUNICODE_STRING NtPath, IN PCWSTR ArcPath, IN PPARTLIST PartList OPTIONAL)
Definition: arcname.c:797
_In_ PVOID Parameter
Definition: ldrtypes.h:239
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2056
enum OPTION_FLAGS Options
Definition: stats.c:44
static PNTOS_INSTALLATION AddNTOSInstallation(IN PGENERIC_LIST List, IN PCWSTR InstallationName, IN USHORT Machine, IN PCWSTR VendorName, IN PCWSTR SystemRootArcPath, IN PUNICODE_STRING SystemRootNtPath, IN PCWSTR PathComponent, IN ULONG DiskNumber, IN ULONG PartitionNumber, IN PPARTENTRY PartEntry OPTIONAL)
Definition: osdetect.c:609
IN PPARTLIST PartList
Definition: osdetect.c:63
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
BOOLEAN NtPathToDiskPartComponents(IN PCWSTR NtPath, OUT PULONG pDiskNumber, OUT PULONG pPartNumber, OUT PCWSTR *PathComponent OPTIONAL)
Definition: filesup.c:771
static const WCHAR SystemRoot[]
Definition: reg.c:38
if(!(yy_init))
Definition: macro.lex.yy.c:717
#define MAX_PATH
Definition: compat.h:26
static PNTOS_INSTALLATION FindExistingNTOSInstall(IN PGENERIC_LIST List, IN PCWSTR SystemRootArcPath OPTIONAL, IN PUNICODE_STRING SystemRootNtPath OPTIONAL)
Definition: osdetect.c:565
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN GetDiskOrPartition(IN PPARTLIST List, IN ULONG DiskNumber, IN ULONG PartitionNumber OPTIONAL, OUT PDISKENTRY *pDiskEntry, OUT PPARTENTRY *pPartEntry OPTIONAL)
Definition: partlist.c:1772
#define DPRINT1
Definition: precomp.h:8
struct _NTOS_OPTIONS * PNTOS_OPTIONS
unsigned int ULONG
Definition: retypes.h:1
const uint16_t * PCWSTR
Definition: typedefs.h:55
IN OUT PGENERIC_LIST List
Definition: osdetect.c:62
PCWSTR OsLoadPath
Definition: bldrsup.h:87
return STATUS_SUCCESS
Definition: btrfs.c:2710
static const WCHAR Signature[]
Definition: parser.c:141
struct _ENUM_INSTALLS_DATA * PENUM_INSTALLS_DATA
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
static PNTOS_INSTALLATION FindExistingNTOSInstall ( IN PGENERIC_LIST  List,
IN PCWSTR SystemRootArcPath  OPTIONAL,
IN PUNICODE_STRING SystemRootNtPath  OPTIONAL 
)
static

Definition at line 565 of file osdetect.c.

Referenced by AddNTOSInstallation(), and EnumerateInstallations().

570 {
572  PNTOS_INSTALLATION NtOsInstall;
573  UNICODE_STRING SystemArcPath;
574 
575  /*
576  * We search either via ARC path or NT path.
577  * If both pointers are NULL then we fail straight away.
578  */
579  if (!SystemRootArcPath && !SystemRootNtPath)
580  return NULL;
581 
582  RtlInitUnicodeString(&SystemArcPath, SystemRootArcPath);
583 
584  for (Entry = GetFirstListEntry(List); Entry; Entry = GetNextListEntry(Entry))
585  {
586  NtOsInstall = (PNTOS_INSTALLATION)GetListEntryData(Entry);
587 
588  /*
589  * Note that if both ARC paths are equal, then the corresponding
590  * NT paths must be the same. However, two ARC paths may be different
591  * but resolve into the same NT path.
592  */
593  if ( (SystemRootArcPath &&
594  RtlEqualUnicodeString(&NtOsInstall->SystemArcPath,
595  &SystemArcPath, TRUE)) ||
596  (SystemRootNtPath &&
597  RtlEqualUnicodeString(&NtOsInstall->SystemNtPath,
598  SystemRootNtPath, TRUE)) )
599  {
600  /* Found it! */
601  return NtOsInstall;
602  }
603  }
604 
605  return NULL;
606 }
Definition: genlist.h:10
#define TRUE
Definition: types.h:120
PGENERIC_LIST_ENTRY GetFirstListEntry(IN PGENERIC_LIST List)
Definition: genlist.c:104
struct _Entry Entry
Definition: kefuncs.h:640
PVOID GetListEntryData(IN PGENERIC_LIST_ENTRY Entry)
Definition: genlist.c:126
PGENERIC_LIST_ENTRY GetNextListEntry(IN PGENERIC_LIST_ENTRY Entry)
Definition: genlist.c:114
smooth NULL
Definition: ftsmooth.c:416
LIST_ENTRY List
Definition: psmgr.c:57
struct _NTOS_INSTALLATION * PNTOS_INSTALLATION
UNICODE_STRING SystemArcPath
Definition: osdetect.h:20
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
UNICODE_STRING SystemNtPath
Definition: osdetect.h:21
static VOID FindNTOSInstallations ( IN OUT PGENERIC_LIST  List,
IN PPARTLIST  PartList,
IN PPARTENTRY  PartEntry 
)
static

Definition at line 682 of file osdetect.c.

Referenced by CreateNTOSInstallationsList().

686 {
688  ULONG DiskNumber = PartEntry->DiskEntry->DiskNumber;
689  ULONG PartitionNumber = PartEntry->PartitionNumber;
690  HANDLE PartitionDirectoryHandle;
693  UNICODE_STRING PartitionRootPath;
695  PVOID BootStoreHandle;
697  ULONG Version;
698  WCHAR PathBuffer[MAX_PATH];
699 
700  /* Set PartitionRootPath */
701  RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
702  L"\\Device\\Harddisk%lu\\Partition%lu\\",
703  DiskNumber, PartitionNumber);
704  RtlInitUnicodeString(&PartitionRootPath, PathBuffer);
705  DPRINT("FindNTOSInstallations: PartitionRootPath: '%wZ'\n", &PartitionRootPath);
706 
707  /* Open the partition */
708  InitializeObjectAttributes(&ObjectAttributes,
709  &PartitionRootPath,
711  NULL,
712  NULL);
713  Status = NtOpenFile(&PartitionDirectoryHandle,
715  &ObjectAttributes,
716  &IoStatusBlock,
719  if (!NT_SUCCESS(Status))
720  {
721  DPRINT1("Failed to open partition '%wZ', Status 0x%08lx\n", &PartitionRootPath, Status);
722  return;
723  }
724 
725  Data.List = List;
726  Data.PartList = PartList;
727 
728  /* Try to see whether we recognize some NT boot loaders */
729  for (Type = FreeLdr; Type < BldrTypeMax; ++Type)
730  {
731  Status = FindBootStore(PartitionDirectoryHandle, Type, &Version);
732  if (!NT_SUCCESS(Status))
733  {
734  /* The loader does not exist, continue with another one */
735  DPRINT("Loader type '%d' does not exist, or an error happened (Status 0x%08lx), continue with another one...\n",
736  Type, Status);
737  continue;
738  }
739 
740  /* The loader exists, try to enumerate its boot entries */
741  DPRINT("Analyze the OS installations for loader type '%d' in disk #%d, partition #%d\n",
742  Type, DiskNumber, PartitionNumber);
743 
744  Status = OpenBootStoreByHandle(&BootStoreHandle, PartitionDirectoryHandle, Type, FALSE);
745  if (!NT_SUCCESS(Status))
746  {
747  DPRINT1("Could not open the NTOS boot store of type '%d' (Status 0x%08lx), continue with another one...\n",
748  Type, Status);
749  continue;
750  }
751  EnumerateBootStoreEntries(BootStoreHandle, EnumerateInstallations, &Data);
752  CloseBootStore(BootStoreHandle);
753  }
754 
755  /* Close the partition */
756  NtClose(PartitionDirectoryHandle);
757 }
DWORD *typedef PVOID
Definition: winlogon.h:61
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:359
Type
Definition: Type.h:6
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
NTSTATUS EnumerateBootStoreEntries(IN PVOID Handle, IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, IN PVOID Parameter OPTIONAL)
Definition: bldrsup.c:1560
PVOID ULONG ULONG PULONG Data
Definition: oprghdlr.h:14
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2056
NTSTATUS CloseBootStore(IN PVOID Handle)
Definition: bldrsup.c:828
#define FILE_SHARE_READ
Definition: compat.h:125
#define FILE_TRAVERSE
Definition: nt_native.h:643
IN PPARTLIST PartList
Definition: osdetect.c:63
#define FALSE
Definition: types.h:117
NTSTATUS FindBootStore(IN HANDLE PartitionDirectoryHandle, IN BOOT_STORE_TYPE Type, OUT PULONG VersionNumber OPTIONAL)
Definition: bldrsup.c:137
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
static __inline NTSTATUS RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1064
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
LONG NTSTATUS
Definition: precomp.h:26
LIST_ENTRY List
Definition: psmgr.c:57
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define MAX_PATH
Definition: compat.h:26
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3393
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1087
#define SYNCHRONIZE
Definition: nt_native.h:61
static NTSTATUS NTAPI EnumerateInstallations(IN BOOT_STORE_TYPE Type, IN PBOOT_STORE_ENTRY BootEntry, IN PVOID Parameter OPTIONAL)
Definition: osdetect.c:70
Status
Definition: gdiplustypes.h:24
enum _BOOT_STORE_TYPE BOOT_STORE_TYPE
DWORD *typedef HANDLE
Definition: winlogon.h:61
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define DPRINT1
Definition: precomp.h:8
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
IN OUT PGENERIC_LIST List
Definition: osdetect.c:62
NTSTATUS OpenBootStoreByHandle(OUT PVOID *Handle, IN HANDLE PartitionDirectoryHandle, IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew)
Definition: bldrsup.c:738
PCWSTR FindSubStrI ( PCWSTR  str,
PCWSTR  strSearch 
)

Definition at line 217 of file osdetect.c.

Referenced by IsValidNTOSInstallationByHandle().

218 {
219  PCWSTR cp = str;
220  PCWSTR s1, s2;
221 
222  if (!*strSearch)
223  return str;
224 
225  while (*cp)
226  {
227  s1 = cp;
228  s2 = strSearch;
229 
230  while (*s1 && *s2 && (towupper(*s1) == towupper(*s2)))
231  ++s1, ++s2;
232 
233  if (!*s2)
234  return cp;
235 
236  ++cp;
237  }
238 
239  return NULL;
240 }
struct S2 s2
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
struct S1 s1
POINT cp
Definition: magnifier.c:60
#define towupper(c)
Definition: wctype.h:99
const uint16_t * PCWSTR
Definition: typedefs.h:55
static BOOLEAN IsValidNTOSInstallation ( IN PUNICODE_STRING  SystemRootPath,
OUT PUSHORT Machine  OPTIONAL,
OUT PUNICODE_STRING VendorName  OPTIONAL 
)
static

Definition at line 500 of file osdetect.c.

Referenced by EnumerateInstallations().

504 {
508  HANDLE SystemRootDirectory;
510 
511  /* Open SystemRootPath */
512  InitializeObjectAttributes(&ObjectAttributes,
513  SystemRootPath,
515  NULL,
516  NULL);
517  Status = NtOpenFile(&SystemRootDirectory,
519  &ObjectAttributes,
520  &IoStatusBlock,
523  if (!NT_SUCCESS(Status))
524  {
525  DPRINT1("Failed to open SystemRoot '%wZ', Status 0x%08lx\n", SystemRootPath, Status);
526  return FALSE;
527  }
528 
529  Success = IsValidNTOSInstallationByHandle(SystemRootDirectory,
530  Machine, VendorName);
531 
532  /* Done! */
533  NtClose(SystemRootDirectory);
534  return Success;
535 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_READ
Definition: compat.h:125
#define FILE_TRAVERSE
Definition: nt_native.h:643
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
unsigned char BOOLEAN
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3393
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define SYNCHRONIZE
Definition: nt_native.h:61
Status
Definition: gdiplustypes.h:24
DWORD *typedef HANDLE
Definition: winlogon.h:61
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define DPRINT1
Definition: precomp.h:8
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static BOOLEAN IsValidNTOSInstallationByHandle(IN HANDLE SystemRootDirectory, OUT PUSHORT Machine OPTIONAL, OUT PUNICODE_STRING VendorName OPTIONAL)
Definition: osdetect.c:346
static BOOLEAN IsValidNTOSInstallationByHandle ( IN HANDLE  SystemRootDirectory,
OUT PUSHORT Machine  OPTIONAL,
OUT PUNICODE_STRING VendorName  OPTIONAL 
)
static

Definition at line 346 of file osdetect.c.

Referenced by IsValidNTOSInstallation().

350 {
352  PCWSTR PathName;
353  USHORT i;
354  USHORT LocalMachine;
355  UNICODE_STRING LocalVendorName;
356  WCHAR VendorNameBuffer[MAX_PATH];
357 
358  /* Check for VendorName validity */
359  if (VendorName->MaximumLength < sizeof(UNICODE_NULL))
360  {
361  /* Don't use it, invalidate the pointer */
362  VendorName = NULL;
363  }
364  else
365  {
366  /* Zero it out */
367  *VendorName->Buffer = UNICODE_NULL;
368  VendorName->Length = 0;
369  }
370 
371  /* Check for the existence of \SystemRoot\System32 */
372  PathName = L"System32\\";
373  if (!DoesDirExist(SystemRootDirectory, PathName))
374  {
375  // DPRINT1("Failed to open directory '%S', Status 0x%08lx\n", PathName, Status);
376  return FALSE;
377  }
378 
379  /* Check for the existence of \SystemRoot\System32\drivers */
380  PathName = L"System32\\drivers\\";
381  if (!DoesDirExist(SystemRootDirectory, PathName))
382  {
383  // DPRINT1("Failed to open directory '%S', Status 0x%08lx\n", PathName, Status);
384  return FALSE;
385  }
386 
387  /* Check for the existence of \SystemRoot\System32\config */
388  PathName = L"System32\\config\\";
389  if (!DoesDirExist(SystemRootDirectory, PathName))
390  {
391  // DPRINT1("Failed to open directory '%S', Status 0x%08lx\n", PathName, Status);
392  return FALSE;
393  }
394 
395 #if 0
396  /*
397  * Check for the existence of SYSTEM and SOFTWARE hives in \SystemRoot\System32\config
398  * (but we don't check here whether they are actually valid).
399  */
400  PathName = L"System32\\config\\SYSTEM";
401  if (!DoesFileExist(SystemRootDirectory, PathName))
402  {
403  // DPRINT1("Failed to open file '%S', Status 0x%08lx\n", PathName, Status);
404  return FALSE;
405  }
406  PathName = L"System32\\config\\SOFTWARE";
407  if (!DoesFileExist(SystemRootDirectory, PathName))
408  {
409  // DPRINT1("Failed to open file '%S', Status 0x%08lx\n", PathName, Status);
410  return FALSE;
411  }
412 #endif
413 
414  RtlInitEmptyUnicodeString(&LocalVendorName, VendorNameBuffer, sizeof(VendorNameBuffer));
415 
416  /* Check for the existence of \SystemRoot\System32\ntoskrnl.exe and retrieves its vendor name */
417  PathName = L"System32\\ntoskrnl.exe";
418  Success = CheckForValidPEAndVendor(SystemRootDirectory, PathName, &LocalMachine, &LocalVendorName);
419  if (!Success)
420  DPRINT1("Kernel executable '%S' is either not a PE file, or does not have any vendor?\n", PathName);
421 
422  /*
423  * The kernel gives the OS its flavour. If we failed due to the absence of
424  * ntoskrnl.exe this might be due to the fact this particular installation
425  * uses a custom kernel that has a different name, overridden in the boot
426  * parameters. We then rely on the existence of ntdll.dll, which cannot be
427  * renamed on a valid NT system.
428  */
429  if (Success)
430  {
431  for (i = 0; i < ARRAYSIZE(KnownVendors); ++i)
432  {
433  Success = !!FindSubStrI(LocalVendorName.Buffer, KnownVendors[i]);
434  if (Success)
435  {
436  /* We have found a correct vendor combination */
437  DPRINT("IsValidNTOSInstallation: We've got an NTOS installation from %S !\n", KnownVendors[i]);
438  break;
439  }
440  }
441 
442  /* Return the target architecture */
443  if (Machine)
444  {
445  /* Copy the value and invalidate the pointer */
446  *Machine = LocalMachine;
447  Machine = NULL;
448  }
449 
450  /* Return the vendor name */
451  if (VendorName)
452  {
453  /* Copy the string and invalidate the pointer */
454  RtlCopyUnicodeString(VendorName, &LocalVendorName);
455  VendorName = NULL;
456  }
457  }
458 
459  /* OPTIONAL: Check for the existence of \SystemRoot\System32\ntkrnlpa.exe */
460 
461  /* Check for the existence of \SystemRoot\System32\ntdll.dll and retrieves its vendor name */
462  PathName = L"System32\\ntdll.dll";
463  Success = CheckForValidPEAndVendor(SystemRootDirectory, PathName, &LocalMachine, &LocalVendorName);
464  if (!Success)
465  DPRINT1("User-mode DLL '%S' is either not a PE file, or does not have any vendor?\n", PathName);
466 
467  if (Success)
468  {
469  for (i = 0; i < ARRAYSIZE(KnownVendors); ++i)
470  {
471  if (!!FindSubStrI(LocalVendorName.Buffer, KnownVendors[i]))
472  {
473  /* We have found a correct vendor combination */
474  DPRINT("IsValidNTOSInstallation: The user-mode DLL '%S' is from %S\n", PathName, KnownVendors[i]);
475  break;
476  }
477  }
478 
479  /* Return the target architecture if not already obtained */
480  if (Machine)
481  {
482  /* Copy the value and invalidate the pointer */
483  *Machine = LocalMachine;
484  Machine = NULL;
485  }
486 
487  /* Return the vendor name if not already obtained */
488  if (VendorName)
489  {
490  /* Copy the string and invalidate the pointer */
491  RtlCopyUnicodeString(VendorName, &LocalVendorName);
492  VendorName = NULL;
493  }
494  }
495 
496  return Success;
497 }
static BOOLEAN CheckForValidPEAndVendor(IN HANDLE RootDirectory OPTIONAL, IN PCWSTR PathNameToFile, OUT PUSHORT Machine, OUT PUNICODE_STRING VendorName)
Definition: osdetect.c:243
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define DoesFileExist(RootDirectory, FileName)
Definition: filesup.h:77
unsigned char BOOLEAN
PCWSTR FindSubStrI(PCWSTR str, PCWSTR strSearch)
Definition: osdetect.c:217
#define MAX_PATH
Definition: compat.h:26
#define DoesDirExist(RootDirectory, DirName)
Definition: filesup.h:74
static const WCHAR L[]
Definition: oid.c:1087
unsigned short USHORT
Definition: pedump.c:61
static const PCWSTR KnownVendors[]
Definition: osdetect.c:29
#define DPRINT1
Definition: precomp.h:8
const uint16_t * PCWSTR
Definition: typedefs.h:55
FORCEINLINE BOOLEAN ShouldICheckThisPartition ( IN PPARTENTRY  PartEntry)

Definition at line 761 of file osdetect.c.

Referenced by CreateNTOSInstallationsList().

763 {
764  if (!PartEntry)
765  return FALSE;
766 
767  return PartEntry->IsPartitioned &&
768  !IsContainerPartition(PartEntry->PartitionType) /* alternatively: PartEntry->PartitionNumber != 0 */ &&
769  !PartEntry->New &&
770  (PartEntry->FormatState == Preformatted /* || PartEntry->FormatState == Formatted */);
771 }
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:245
#define FALSE
Definition: types.h:117

Variable Documentation

const PCWSTR KnownVendors[] = { VENDOR_REACTOS, VENDOR_MICROSOFT }
static

Definition at line 29 of file osdetect.c.

Referenced by IsValidNTOSInstallationByHandle().