ReactOS  0.4.13-dev-241-g63286c6
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 
24 typedef struct _SMBIOS21_ENTRY_POINT
25 {
41 
42 typedef struct _SMBIOS30_ENTRY_POINT
43 {
55 
56 static
57 BOOLEAN
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 
127 NTSTATUS
128 NTAPI
129 WmipGetRawSMBiosTableData(
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");
187  }
188 
189  /* Copy the header */
190  RtlCopyMemory(BiosTables, &BiosTablesHeader, HeaderSize);
191 
192  /* This is where the table is */
193  PhysicalAddress.QuadPart = TableAddress;
194 
195  /* Map the table into the system address space */
197  if (TableMapping == NULL)
198  {
199  ExFreePoolWithTag(BiosTables, 'BTMS');
200  return STATUS_UNSUCCESSFUL;
201  }
202 
203  /* Copy the table */
204  RtlCopyMemory((PUCHAR)BiosTables + HeaderSize, TableMapping, TableSize);
205 
206  /* Unmap the table */
207  MmUnmapIoSpace(TableMapping, TableSize);
208 
209  *OutTableData = BiosTables;
210  }
211 
212  *OutDataSize = HeaderSize + TableSize;
213  return STATUS_SUCCESS;
214 }
215 
216 
217 NTSTATUS
218 NTAPI
220  _Inout_ ULONG *InOutBufferSize,
221  _Out_opt_ PVOID OutBuffer)
222 {
224  PVOID TableData = NULL;
225  ULONG TableSize, ResultSize;
226  PWNODE_ALL_DATA AllData;
227 
228  /* Get the table data */
229  Status = WmipGetRawSMBiosTableData(OutBuffer ? &TableData : NULL, &TableSize);
230  if (!NT_SUCCESS(Status))
231  {
232  DPRINT1("WmipGetRawSMBiosTableData failed: 0x%08lx\n", Status);
233  return Status;
234  }
235 
236  ResultSize = sizeof(WNODE_ALL_DATA) + TableSize;
237 
238  /* Check if the caller provided a buffer */
239  if ((OutBuffer != NULL) && (*InOutBufferSize != 0))
240  {
241  /* Check if the buffer is large enough */
242  if (*InOutBufferSize < ResultSize)
243  {
244  DPRINT1("Buffer too small. Got %lu, need %lu\n",
245  *InOutBufferSize, ResultSize);
247  }
248 
250  AllData = OutBuffer;
251  AllData->WnodeHeader.BufferSize = ResultSize;
252  AllData->WnodeHeader.ProviderId = 0;
253  AllData->WnodeHeader.Version = 0;
254  AllData->WnodeHeader.Linkage = 0; // last entry
255  //AllData->WnodeHeader.CountLost;
256  AllData->WnodeHeader.KernelHandle = NULL;
257  //AllData->WnodeHeader.TimeStamp;
259  //AllData->WnodeHeader.ClientContext;
261  AllData->DataBlockOffset = sizeof(WNODE_ALL_DATA);
262  AllData->InstanceCount = 1;
263  //AllData->OffsetInstanceNameOffsets;
264  AllData->FixedInstanceSize = TableSize;
265 
266  RtlCopyMemory(AllData + 1, TableData, TableSize);
267  }
268 
269  /* Set the size */
270  *InOutBufferSize = ResultSize;
271 
272  /* Free the table buffer */
273  if (TableData != NULL)
274  {
275  ExFreePoolWithTag(TableData, 'BTMS');
276  }
277 
278  return STATUS_SUCCESS;
279 }
280 
#define _Outptr_opt_result_buffer_(size)
Definition: no_sal2.h:398
ULONG TableMaxSize
Definition: smbios.c:52
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
CHAR AnchorString[5]
Definition: smbios.c:44
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
struct _SMBIOS30_ENTRY_POINT SMBIOS30_ENTRY_POINT
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
struct tagWNODE_ALL_DATA WNODE_ALL_DATA
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
struct _SMBIOS21_ENTRY_POINT * PSMBIOS21_ENTRY_POINT
UCHAR Checksum2
Definition: smbios.c:35
unsigned char BOOLEAN
CHAR FormattedArea[5]
Definition: smbios.c:33
smooth NULL
Definition: ftsmooth.c:416
USHORT MaxStructureSize
Definition: smbios.c:31
#define _Out_
Definition: no_sal2.h:323
#define _At_(target, annos)
Definition: no_sal2.h:11
UCHAR Length
Definition: smbios.c:46
ULONG DataBlockOffset
Definition: wmistr.h:113
#define _Out_opt_
Definition: no_sal2.h:339
#define STATUS_NOT_FOUND
Definition: shellext.h:67
#define __drv_allocatesMem(kind)
Definition: driverspecs.h:239
const GUID MSSmBios_RawSMBiosTables_GUID
Definition: hwhacks.c:20
UCHAR Reserved
Definition: smbios.c:51
#define WNODE_FLAG_FIXED_INSTANCE_SIZE
Definition: wmistr.h:32
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CHAR AnchorString[4]
Definition: smbios.c:26
USHORT NumberOfStructures
Definition: smbios.c:38
UCHAR MajorVersion
Definition: smbios.c:47
#define _Inout_
Definition: no_sal2.h:244
struct _SMBIOS21_ENTRY_POINT SMBIOS21_ENTRY_POINT
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned __int64 ULONG64
Definition: imports.h:198
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1060
Definition: smbios.c:42
unsigned char UCHAR
Definition: xmlstorage.h:181
Definition: smbios.c:24
UCHAR EntryPointRevision
Definition: smbios.c:32
USHORT TableLength
Definition: smbios.c:36
Status
Definition: gdiplustypes.h:24
ULONG TableAddress
Definition: smbios.c:37
#define _In_
Definition: no_sal2.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:78
struct _SMBIOS30_ENTRY_POINT * PSMBIOS30_ENTRY_POINT
unsigned short USHORT
Definition: pedump.c:61
UCHAR MinorVersion
Definition: smbios.c:48
ULONG FixedInstanceSize
Definition: wmistr.h:118
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
UCHAR Revision
Definition: smbios.c:50
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int * PULONG
Definition: retypes.h:1
UCHAR Checksum
Definition: smbios.c:45
ULONG64 TableAddress
Definition: smbios.c:53
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ typedef _Out_ PULONG TableSize
Definition: iotypes.h:3970
unsigned int ULONG
Definition: retypes.h:1
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:112
unsigned __int64 * PULONG64
Definition: imports.h:198
NTSTATUS NTAPI WmipQueryRawSMBiosTables(_Inout_ ULONG *InOutBufferSize, _Out_opt_ PVOID OutBuffer)
Definition: smbios.c:219
UCHAR Docref
Definition: smbios.c:49
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
_At_ * OutTableData(Mem)) NTSTATUSNTAPIWmipGetRawSMBiosTableData(_Outptr_opt_result_buffer_(*OutDataSize) PVOID *OutTableData, _Out_ PULONG OutDataSize
Definition: smbios.c:126
UCHAR MajorVersion
Definition: smbios.c:29
UCHAR Checksum
Definition: smbios.c:27
return STATUS_SUCCESS
Definition: btrfs.c:2745
UCHAR BCDRevision
Definition: smbios.c:39
UCHAR MinorVersion
Definition: smbios.c:30
ULONG InstanceCount
Definition: wmistr.h:114
CHAR AnchorString2[5]
Definition: smbios.c:34
UCHAR Length
Definition: smbios.c:28
static BOOLEAN GetEntryPointData(_In_ const UCHAR *EntryPointAddress, _Out_ PULONG64 TableAddress, _Out_ PULONG TableSize, _Out_ PMSSmBios_RawSMBiosTables BiosTablesHeader)
Definition: smbios.c:58
LONGLONG QuadPart
Definition: typedefs.h:112