ReactOS  0.4.14-dev-317-g96040ec
ntverrsrc.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Setup Library
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: NT Version Resource Management API
5  * COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito
6  *
7  * NOTE 1: Adapted from Wine-synced dll/win32/version DLL.
8  * NOTE 2: We only deal with 32-bit PE executables.
9  */
10 
11 /* INCLUDES *****************************************************************/
12 
13 #include "precomp.h"
14 #include <ndk/ldrtypes.h>
15 #include <ndk/ldrfuncs.h>
16 
17 #include "ntverrsrc.h"
18 
19 #define NDEBUG
20 #include <debug.h>
21 
22 
23 /* FUNCTIONS ****************************************************************/
24 
29  OUT PULONG ResourceSize OPTIONAL)
30 {
31 // #define RT_VERSION MAKEINTRESOURCE(16) // See winuser.h
32 #define VS_VERSION_INFO 1 // See psdk/verrsrc.h
33 #define VS_FILE_INFO RT_VERSION
34 
36  LDR_RESOURCE_INFO ResourceInfo;
37  PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
38  PVOID Data = NULL;
39  ULONG Size = 0;
40 
41  /* Try to find the resource */
42  ResourceInfo.Type = 16; // RT_VERSION;
43  ResourceInfo.Name = VS_VERSION_INFO; // MAKEINTRESOURCEW(VS_VERSION_INFO);
44  ResourceInfo.Language = 0; // Don't care about the language
45 
47  &ResourceInfo,
49  &ResourceDataEntry);
50  if (!NT_SUCCESS(Status))
51  {
52  DPRINT1("NtGetVersionResource: Version resource not found, Status 0x%08lx\n", Status);
53  return Status;
54  }
55 
56  /* Access the resource */
58  ResourceDataEntry,
59  &Data,
60  &Size);
61  if (!NT_SUCCESS(Status))
62  {
63  DPRINT1("NtGetVersionResource: Cannot access Version resource, Status 0x%08lx\n", Status);
64  return Status;
65  }
66 
67  *Resource = Data;
68  if (ResourceSize) *ResourceSize = Size;
69 
70  return STATUS_SUCCESS;
71 }
72 
73 /* NOTE: the xxx_STRUCT16 version differs by storing strings in ANSI, not in UNICODE */
75 {
78  WORD wType; /* 1:Text, 0:Binary */
80 #if 0 /* variable length structure */
81  /* DWORD aligned */
82  BYTE Value[];
83  /* DWORD aligned */
84  VS_VERSION_INFO_STRUCT32 Children[];
85 #endif
88 
89 #define DWORD_ALIGN( base, ptr ) \
90  ( (ULONG_PTR)(base) + ((((ULONG_PTR)(ptr) - (ULONG_PTR)(base)) + 3) & ~3) )
91 
92 #define VersionInfo32_Value( ver ) \
93  DWORD_ALIGN( (ver), (ver)->szKey + wcslen((ver)->szKey) + 1 )
94 
95 #define VersionInfo32_Children( ver ) \
96  (PCVS_VERSION_INFO_STRUCT32)( VersionInfo32_Value( ver ) + \
97  ( ( (ver)->wValueLength * \
98  ((ver)->wType? 2 : 1) + 3 ) & ~3 ) )
99 
100 #define VersionInfo32_Next( ver ) \
101  (PVS_VERSION_INFO_STRUCT32)( (ULONG_PTR)ver + (((ver)->wLength + 3) & ~3) )
102 
106  IN PCWSTR szKey,
107  IN UINT cchKey)
108 {
110 
111  while ((ULONG_PTR)child < (ULONG_PTR)info + info->wLength)
112  {
113  if (!_wcsnicmp(child->szKey, szKey, cchKey) && !child->szKey[cchKey])
114  return child;
115 
116  if (child->wLength == 0) return NULL;
118  }
119 
120  return NULL;
121 }
122 
123 static NTSTATUS
126  IN PCWSTR lpSubBlock,
127  OUT PVOID* lplpBuffer,
128  OUT PUINT puLen OPTIONAL,
129  OUT BOOL* pbText OPTIONAL)
130 {
131  PCWSTR lpNextSlash;
132 
133  DPRINT("lpSubBlock : (%S)\n", lpSubBlock);
134 
135  while (*lpSubBlock)
136  {
137  /* Find next path component */
138  for (lpNextSlash = lpSubBlock; *lpNextSlash; lpNextSlash++)
139  {
140  if (*lpNextSlash == '\\')
141  break;
142  }
143 
144  /* Skip empty components */
145  if (lpNextSlash == lpSubBlock)
146  {
147  lpSubBlock++;
148  continue;
149  }
150 
151  /* We have a non-empty component: search info for key */
152  info = VersionInfo32_FindChild(info, lpSubBlock, lpNextSlash - lpSubBlock);
153  if (!info)
154  {
155  if (puLen) *puLen = 0;
157  }
158 
159  /* Skip path component */
160  lpSubBlock = lpNextSlash;
161  }
162 
163  /* Return value */
164  *lplpBuffer = (PVOID)VersionInfo32_Value(info);
165  if (puLen)
166  *puLen = info->wValueLength;
167  if (pbText)
168  *pbText = info->wType;
169 
170  return STATUS_SUCCESS;
171 }
172 
173 NTSTATUS
175  IN const VOID* pBlock,
176  IN PCWSTR lpSubBlock,
177  OUT PVOID* lplpBuffer,
178  OUT PUINT puLen)
179 {
181 
182  DPRINT("%s (%p, %S, %p, %p)\n", __FUNCTION__, pBlock, lpSubBlock, lplpBuffer, puLen);
183 
184  if (!pBlock)
185  return FALSE;
186 
187  if (!lpSubBlock || !*lpSubBlock)
188  lpSubBlock = L"\\";
189 
190  return VersionInfo32_QueryValue(info, lpSubBlock, lplpBuffer, puLen, NULL);
191 }
192 
193 /* EOF */
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
struct _VS_VERSION_INFO_STRUCT32 VS_VERSION_INFO_STRUCT32
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
const VS_VERSION_INFO_STRUCT32 * PCVS_VERSION_INFO_STRUCT32
Definition: ntverrsrc.c:87
LONG NTSTATUS
Definition: precomp.h:26
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
static HWND child
Definition: cursoricon.c:298
ULONG_PTR Type
Definition: ldrtypes.h:181
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
NTSTATUS NtGetVersionResource(IN PVOID BaseAddress, OUT PVOID *Resource, OUT PULONG ResourceSize OPTIONAL)
Definition: ntverrsrc.c:26
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
unsigned int BOOL
Definition: ntddk_ex.h:94
struct _VS_VERSION_INFO_STRUCT32 * PVS_VERSION_INFO_STRUCT32
ULONG_PTR Name
Definition: ldrtypes.h:182
smooth NULL
Definition: ftsmooth.c:416
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
void DPRINT(...)
Definition: polytest.cpp:61
Definition: pedump.c:457
NTSTATUS NTAPI LdrFindResource_U(_In_ PVOID BaseAddress, _In_ PLDR_RESOURCE_INFO ResourceInfo, _In_ ULONG Level, _Out_ PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry)
void * PVOID
Definition: retypes.h:9
NTSTATUS NTAPI LdrAccessResource(_In_ PVOID BaseAddress, _In_ PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry, _Out_opt_ PVOID *Resource, _Out_opt_ PULONG Size)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
static PCVS_VERSION_INFO_STRUCT32 VersionInfo32_FindChild(IN PCVS_VERSION_INFO_STRUCT32 info, IN PCWSTR szKey, IN UINT cchKey)
Definition: ntverrsrc.c:104
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned short WORD
Definition: ntddk_ex.h:93
static NTSTATUS VersionInfo32_QueryValue(IN PCVS_VERSION_INFO_STRUCT32 info, IN PCWSTR lpSubBlock, OUT PVOID *lplpBuffer, OUT PUINT puLen OPTIONAL, OUT BOOL *pbText OPTIONAL)
Definition: ntverrsrc.c:124
#define VersionInfo32_Value(ver)
Definition: ntverrsrc.c:92
static const WCHAR L[]
Definition: oid.c:1250
unsigned char BYTE
Definition: mem.h:68
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
#define RESOURCE_DATA_LEVEL
Definition: ldrtypes.h:33
unsigned int * PULONG
Definition: retypes.h:1
unsigned int UINT
Definition: ndis.h:50
#define VS_VERSION_INFO
#define DPRINT1
Definition: precomp.h:8
ULONG_PTR Language
Definition: ldrtypes.h:183
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define VersionInfo32_Next(ver)
Definition: ntverrsrc.c:100
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define __FUNCTION__
Definition: types.h:112
unsigned int * PUINT
Definition: ndis.h:50
#define VersionInfo32_Children(ver)
Definition: ntverrsrc.c:95
#define STATUS_RESOURCE_TYPE_NOT_FOUND
Definition: ntstatus.h:360
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68