ReactOS 0.4.15-dev-7934-g1dc8d80
smbios.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/wmi/smbios.c
5 * PURPOSE: I/O Windows Management Instrumentation (WMI) Support
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include <ntoskrnl.h>
12#include <wmiguid.h>
13#include <wmidata.h>
14#include <wmistr.h>
15
16#include "wmip.h"
17
18#define NDEBUG
19#include <debug.h>
20
21
22/* FUNCTIONS *****************************************************************/
23
25{
41
43{
55
56static
59 _In_ const UCHAR *EntryPointAddress,
60 _Out_ PULONG64 TableAddress,
62 _Out_ PMSSmBios_RawSMBiosTables BiosTablesHeader)
63{
64 PSMBIOS21_ENTRY_POINT EntryPoint21;
65 PSMBIOS30_ENTRY_POINT EntryPoint30;
66 UCHAR Checksum;
67 ULONG i;
68
69 /* Check for SMBIOS 2.1 entry point */
70 EntryPoint21 = (PSMBIOS21_ENTRY_POINT)EntryPointAddress;
71 if (RtlEqualMemory(EntryPoint21->AnchorString, "_SM_", 4))
72 {
73 if (EntryPoint21->Length > 32)
74 return FALSE;
75
76 /* Calculate the checksum */
77 Checksum = 0;
78 for (i = 0; i < EntryPoint21->Length; i++)
79 {
80 Checksum += EntryPointAddress[i];
81 }
82
83 if (Checksum != 0)
84 return FALSE;
85
86 *TableAddress = EntryPoint21->TableAddress;
87 *TableSize = EntryPoint21->TableLength;
88 BiosTablesHeader->Used20CallingMethod = 0;
89 BiosTablesHeader->SmbiosMajorVersion = EntryPoint21->MajorVersion;
90 BiosTablesHeader->SmbiosMinorVersion = EntryPoint21->MinorVersion;
91 BiosTablesHeader->DmiRevision = 2;
92 BiosTablesHeader->Size = EntryPoint21->TableLength;
93 return TRUE;
94 }
95
96 /* Check for SMBIOS 3.0 entry point */
97 EntryPoint30 = (PSMBIOS30_ENTRY_POINT)EntryPointAddress;
98 if (RtlEqualMemory(EntryPoint30->AnchorString, "_SM3_", 5))
99 {
100 if (EntryPoint30->Length > 32)
101 return FALSE;
102
103 /* Calculate the checksum */
104 Checksum = 0;
105 for (i = 0; i < EntryPoint30->Length; i++)
106 {
107 Checksum += EntryPointAddress[i];
108 }
109
110 if (Checksum != 0)
111 return FALSE;
112
113 *TableAddress = EntryPoint30->TableAddress;
114 *TableSize = EntryPoint30->TableMaxSize;
115 BiosTablesHeader->Used20CallingMethod = 0;
116 BiosTablesHeader->SmbiosMajorVersion = EntryPoint30->MajorVersion;
117 BiosTablesHeader->SmbiosMinorVersion = EntryPoint30->MinorVersion;
118 BiosTablesHeader->DmiRevision = 3;
119 BiosTablesHeader->Size = EntryPoint30->TableMaxSize;
120 return TRUE;
121 }
122
123 return FALSE;
124}
125
128NTAPI
129WmipGetRawSMBiosTableData(
131 _Out_ PULONG OutDataSize)
132{
133 static const SIZE_T SearchSize = 0x10000;
134 static const ULONG HeaderSize = FIELD_OFFSET(MSSmBios_RawSMBiosTables, SMBiosData);
136 PUCHAR EntryPointMapping;
137 MSSmBios_RawSMBiosTables BiosTablesHeader;
138 PVOID BiosTables, TableMapping;
140 ULONG64 TableAddress = 0;
141
142 /* This is where the range for the entry point starts */
143 PhysicalAddress.QuadPart = 0xF0000;
144
145 /* Map the range into the system address space */
146 EntryPointMapping = MmMapIoSpace(PhysicalAddress, SearchSize, MmCached);
147 if (EntryPointMapping == NULL)
148 {
149 DPRINT1("Failed to map range for SMBIOS entry point\n");
150 return STATUS_UNSUCCESSFUL;
151 }
152
153 /* Loop the table memory in 16 byte steps */
154 for (Offset = 0; Offset <= (0x10000 - 32); Offset += 16)
155 {
156 /* Check if we have an entry point here and get it's data */
157 if (GetEntryPointData(EntryPointMapping + Offset,
158 &TableAddress,
159 &TableSize,
160 &BiosTablesHeader))
161 {
162 break;
163 }
164 }
165
166 /* Unmap the entry point */
167 MmUnmapIoSpace(EntryPointMapping, SearchSize);
168
169 /* Did we find anything */
170 if (TableAddress == 0)
171 {
172 DPRINT1("Could not find the SMBIOS entry point\n");
173 return STATUS_NOT_FOUND;
174 }
175
176 /* Check if the caller asked for the buffer */
177 if (OutTableData != NULL)
178 {
179 /* Allocate a buffer for the result */
180 BiosTables = ExAllocatePoolWithTag(PagedPool,
181 HeaderSize + TableSize,
182 'BTMS');
183 if (BiosTables == NULL)
184 {
185 DPRINT1("Failed to allocate %lu bytes for the SMBIOS table\n",
186 HeaderSize + TableSize);
188 }
189
190 /* Copy the header */
191 RtlCopyMemory(BiosTables, &BiosTablesHeader, HeaderSize);
192
193 /* This is where the table is */
194 PhysicalAddress.QuadPart = TableAddress;
195
196 /* Map the table into the system address space */
198 if (TableMapping == NULL)
199 {
200 ExFreePoolWithTag(BiosTables, 'BTMS');
201 return STATUS_UNSUCCESSFUL;
202 }
203
204 /* Copy the table */
205 RtlCopyMemory((PUCHAR)BiosTables + HeaderSize, TableMapping, TableSize);
206
207 /* Unmap the table */
208 MmUnmapIoSpace(TableMapping, TableSize);
209
210 *OutTableData = BiosTables;
211 }
212
213 *OutDataSize = HeaderSize + TableSize;
214 return STATUS_SUCCESS;
215}
216
217
219NTAPI
221 _Inout_ ULONG *InOutBufferSize,
223{
225 PVOID TableData = NULL;
226 ULONG TableSize, ResultSize;
227 PWNODE_ALL_DATA AllData;
228
229 /* Get the table data */
230 Status = WmipGetRawSMBiosTableData(OutBuffer ? &TableData : NULL, &TableSize);
231 if (!NT_SUCCESS(Status))
232 {
233 DPRINT1("WmipGetRawSMBiosTableData failed: 0x%08lx\n", Status);
234 return Status;
235 }
236
237 ResultSize = sizeof(WNODE_ALL_DATA) + TableSize;
238
239 /* Check if the caller provided a buffer */
240 if ((OutBuffer != NULL) && (*InOutBufferSize != 0))
241 {
242 /* Check if the buffer is large enough */
243 if (*InOutBufferSize < ResultSize)
244 {
245 DPRINT1("Buffer too small. Got %lu, need %lu\n",
246 *InOutBufferSize, ResultSize);
248 }
249
251 AllData = OutBuffer;
252 AllData->WnodeHeader.BufferSize = ResultSize;
253 AllData->WnodeHeader.ProviderId = 0;
254 AllData->WnodeHeader.Version = 0;
255 AllData->WnodeHeader.Linkage = 0; // last entry
256 //AllData->WnodeHeader.CountLost;
257 AllData->WnodeHeader.KernelHandle = NULL;
258 //AllData->WnodeHeader.TimeStamp;
260 //AllData->WnodeHeader.ClientContext;
262 AllData->DataBlockOffset = sizeof(WNODE_ALL_DATA);
263 AllData->InstanceCount = 1;
264 //AllData->OffsetInstanceNameOffsets;
265 AllData->FixedInstanceSize = TableSize;
266
267 RtlCopyMemory(AllData + 1, TableData, TableSize);
268 }
269
270 /* Set the size */
271 *InOutBufferSize = ResultSize;
272
273 /* Free the table buffer */
274 if (TableData != NULL)
275 {
276 ExFreePoolWithTag(TableData, 'BTMS');
277 }
278
279 return STATUS_SUCCESS;
280}
281
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define __drv_allocatesMem(kind)
Definition: driverspecs.h:257
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const GUID MSSmBios_RawSMBiosTables_GUID
Definition: hwhacks.c:20
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
#define RtlEqualMemory(a, b, c)
Definition: kdvm.h:18
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
unsigned __int64 * PULONG64
Definition: imports.h:198
unsigned __int64 ULONG64
Definition: imports.h:198
#define _Outptr_opt_result_buffer_(size)
Definition: ms_sal.h:457
#define _Out_opt_
Definition: ms_sal.h:346
#define _Inout_
Definition: ms_sal.h:378
#define _At_(target, annos)
Definition: ms_sal.h:244
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
struct _SMBIOS30_ENTRY_POINT * PSMBIOS30_ENTRY_POINT
_At_ * OutTableData(Mem)) NTSTATUSNTAPIWmipGetRawSMBiosTableData(_Outptr_opt_result_buffer_(*OutDataSize) PVOID *OutTableData, _Out_ PULONG OutDataSize
Definition: smbios.c:126
struct _SMBIOS30_ENTRY_POINT SMBIOS30_ENTRY_POINT
static BOOLEAN GetEntryPointData(_In_ const UCHAR *EntryPointAddress, _Out_ PULONG64 TableAddress, _Out_ PULONG TableSize, _Out_ PMSSmBios_RawSMBiosTables BiosTablesHeader)
Definition: smbios.c:58
struct _SMBIOS21_ENTRY_POINT * PSMBIOS21_ENTRY_POINT
NTSTATUS NTAPI WmipQueryRawSMBiosTables(_Inout_ ULONG *InOutBufferSize, _Out_opt_ PVOID OutBuffer)
Definition: smbios.c:220
struct _SMBIOS21_ENTRY_POINT SMBIOS21_ENTRY_POINT
unsigned short USHORT
Definition: pedump.c:61
_In_ UCHAR _In_ ULONG _Out_ PUCHAR _Outptr_result_bytebuffer_ OutBufferLength PVOID * OutBuffer
Definition: scsi.h:4071
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
Definition: smbios.c:25
CHAR FormattedArea[5]
Definition: smbios.c:33
USHORT MaxStructureSize
Definition: smbios.c:31
UCHAR Checksum
Definition: smbios.c:27
ULONG TableAddress
Definition: smbios.c:37
UCHAR Checksum2
Definition: smbios.c:35
CHAR AnchorString2[5]
Definition: smbios.c:34
UCHAR Length
Definition: smbios.c:28
CHAR AnchorString[4]
Definition: smbios.c:26
UCHAR MinorVersion
Definition: smbios.c:30
UCHAR MajorVersion
Definition: smbios.c:29
UCHAR EntryPointRevision
Definition: smbios.c:32
USHORT NumberOfStructures
Definition: smbios.c:38
USHORT TableLength
Definition: smbios.c:36
UCHAR BCDRevision
Definition: smbios.c:39
Definition: smbios.c:43
UCHAR Docref
Definition: smbios.c:49
UCHAR Checksum
Definition: smbios.c:45
CHAR AnchorString[5]
Definition: smbios.c:44
UCHAR Length
Definition: smbios.c:46
UCHAR Reserved
Definition: smbios.c:51
ULONG TableMaxSize
Definition: smbios.c:52
UCHAR MajorVersion
Definition: smbios.c:47
UCHAR MinorVersion
Definition: smbios.c:48
ULONG64 TableAddress
Definition: smbios.c:53
UCHAR Revision
Definition: smbios.c:50
ULONG InstanceCount
Definition: wmistr.h:114
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:112
ULONG DataBlockOffset
Definition: wmistr.h:113
ULONG FixedInstanceSize
Definition: wmistr.h:118
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
#define WNODE_FLAG_FIXED_INSTANCE_SIZE
Definition: wmistr.h:32
struct tagWNODE_ALL_DATA WNODE_ALL_DATA
_Must_inspect_result_ typedef _Out_ PULONG TableSize
Definition: iotypes.h:4327
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
@ MmCached
Definition: mmtypes.h:130
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175