ReactOS 0.4.16-dev-981-g80eb313
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
25#define MAKEINTRESOURCE(i) ((ULONG_PTR)(USHORT)(i))
26#define RT_VERSION MAKEINTRESOURCE(16) // See psdk/winuser.h
27#define VS_VERSION_INFO 1 // See psdk/verrsrc.h
28#define VS_FILE_INFO RT_VERSION
29
34 OUT PULONG ResourceSize OPTIONAL)
35{
37 LDR_RESOURCE_INFO ResourceInfo;
38 PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
39 PVOID Data = NULL;
40 ULONG Size = 0;
41
42 /* Try to find the resource (language-neutral) */
43 ResourceInfo.Type = RT_VERSION;
44 ResourceInfo.Name = VS_VERSION_INFO;
46
48 &ResourceInfo,
50 &ResourceDataEntry);
51 if (!NT_SUCCESS(Status))
52 {
53 DPRINT1("NtGetVersionResource: Version resource not found, Status 0x%08lx\n", Status);
54 return Status;
55 }
56
57 /* Access the resource */
59 ResourceDataEntry,
60 &Data,
61 &Size);
62 if (!NT_SUCCESS(Status))
63 {
64 DPRINT1("NtGetVersionResource: Cannot access Version resource, Status 0x%08lx\n", Status);
65 return Status;
66 }
67
68 *Resource = Data;
69 if (ResourceSize) *ResourceSize = Size;
70
71 return STATUS_SUCCESS;
72}
73
74/* NOTE: the xxx_STRUCT16 version differs by storing strings in ANSI, not in UNICODE */
76{
79 WORD wType; /* 1:Text, 0:Binary */
81#if 0 /* variable length structure */
82 /* DWORD aligned */
83 BYTE Value[];
84 /* DWORD aligned */
85 VS_VERSION_INFO_STRUCT32 Children[];
86#endif
89
90#define DWORD_ALIGN( base, ptr ) \
91 ( (ULONG_PTR)(base) + ((((ULONG_PTR)(ptr) - (ULONG_PTR)(base)) + 3) & ~3) )
92
93#define VersionInfo32_Value( ver ) \
94 DWORD_ALIGN( (ver), (ver)->szKey + wcslen((ver)->szKey) + 1 )
95
96#define VersionInfo32_Children( ver ) \
97 (PCVS_VERSION_INFO_STRUCT32)( VersionInfo32_Value( ver ) + \
98 ( ( (ver)->wValueLength * \
99 ((ver)->wType? 2 : 1) + 3 ) & ~3 ) )
100
101#define VersionInfo32_Next( ver ) \
102 (PVS_VERSION_INFO_STRUCT32)( (ULONG_PTR)ver + (((ver)->wLength + 3) & ~3) )
103
107 IN PCWSTR szKey,
108 IN UINT cchKey)
109{
111
112 while ((ULONG_PTR)child < (ULONG_PTR)info + info->wLength)
113 {
114 if (!_wcsnicmp(child->szKey, szKey, cchKey) && !child->szKey[cchKey])
115 return child;
116
117 if (child->wLength == 0) return NULL;
119 }
120
121 return NULL;
122}
123
124static NTSTATUS
127 IN PCWSTR lpSubBlock,
128 OUT PVOID* lplpBuffer,
129 OUT PUINT puLen OPTIONAL,
130 OUT BOOL* pbText OPTIONAL)
131{
132 PCWSTR lpNextSlash;
133
134 DPRINT("lpSubBlock : (%S)\n", lpSubBlock);
135
136 while (*lpSubBlock)
137 {
138 /* Find next path component */
139 for (lpNextSlash = lpSubBlock; *lpNextSlash; lpNextSlash++)
140 {
141 if (*lpNextSlash == '\\')
142 break;
143 }
144
145 /* Skip empty components */
146 if (lpNextSlash == lpSubBlock)
147 {
148 lpSubBlock++;
149 continue;
150 }
151
152 /* We have a non-empty component: search info for key */
153 info = VersionInfo32_FindChild(info, lpSubBlock, lpNextSlash - lpSubBlock);
154 if (!info)
155 {
156 if (puLen) *puLen = 0;
158 }
159
160 /* Skip path component */
161 lpSubBlock = lpNextSlash;
162 }
163
164 /* Return value */
165 *lplpBuffer = (PVOID)VersionInfo32_Value(info);
166 if (puLen)
167 *puLen = info->wValueLength;
168 if (pbText)
169 *pbText = info->wType;
170
171 return STATUS_SUCCESS;
172}
173
176 IN const VOID* pBlock,
177 IN PCWSTR lpSubBlock,
178 OUT PVOID* lplpBuffer,
179 OUT PUINT puLen)
180{
182
183 DPRINT("%s (%p, %S, %p, %p)\n", __FUNCTION__, pBlock, lpSubBlock, lplpBuffer, puLen);
184
185 if (!pBlock)
186 return FALSE;
187
188 if (!lpSubBlock || !*lpSubBlock)
189 lpSubBlock = L"\\";
190
191 return VersionInfo32_QueryValue(info, lpSubBlock, lplpBuffer, puLen, NULL);
192}
193
194/* EOF */
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:843
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define __FUNCTION__
Definition: types.h:116
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned short WORD
Definition: ntddk_ex.h:93
Status
Definition: gdiplustypes.h:25
NTSTATUS NTAPI LdrAccessResource(_In_ PVOID BaseAddress, _In_ PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry, _Out_opt_ PVOID *Resource, _Out_opt_ PULONG Size)
NTSTATUS NTAPI LdrFindResource_U(_In_ PVOID BaseAddress, _In_ PLDR_RESOURCE_INFO ResourceInfo, _In_ ULONG Level, _Out_ PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry)
#define RESOURCE_DATA_LEVEL
Definition: ldrtypes.h:33
static HWND child
Definition: cursoricon.c:298
unsigned int * PUINT
Definition: ndis.h:50
unsigned int UINT
Definition: ndis.h:50
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define STATUS_RESOURCE_TYPE_NOT_FOUND
Definition: ntstatus.h:374
#define L(x)
Definition: ntvdm.h:50
#define VersionInfo32_Next(ver)
Definition: ntverrsrc.c:101
struct _VS_VERSION_INFO_STRUCT32 VS_VERSION_INFO_STRUCT32
const VS_VERSION_INFO_STRUCT32 * PCVS_VERSION_INFO_STRUCT32
Definition: ntverrsrc.c:88
#define VersionInfo32_Value(ver)
Definition: ntverrsrc.c:93
NTSTATUS NtGetVersionResource(IN PVOID BaseAddress, OUT PVOID *Resource, OUT PULONG ResourceSize OPTIONAL)
Definition: ntverrsrc.c:31
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:125
static PCVS_VERSION_INFO_STRUCT32 VersionInfo32_FindChild(IN PCVS_VERSION_INFO_STRUCT32 info, IN PCWSTR szKey, IN UINT cchKey)
Definition: ntverrsrc.c:105
#define VersionInfo32_Children(ver)
Definition: ntverrsrc.c:96
#define VS_VERSION_INFO
Definition: ntverrsrc.c:27
NTSTATUS NtVerQueryValue(IN const VOID *pBlock, IN PCWSTR lpSubBlock, OUT PVOID *lplpBuffer, OUT PUINT puLen)
Definition: ntverrsrc.c:175
#define RT_VERSION
Definition: ntverrsrc.c:26
struct _VS_VERSION_INFO_STRUCT32 * PVS_VERSION_INFO_STRUCT32
_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)
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_NEUTRAL
Definition: nls.h:167
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
Definition: pedump.c:458
ULONG_PTR Language
Definition: ldrtypes.h:187
ULONG_PTR Name
Definition: ldrtypes.h:186
ULONG_PTR Type
Definition: ldrtypes.h:185
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193