ReactOS 0.4.16-dev-334-g4d9f67c
id.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS PCI Bus Driver
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/bus/pci/pci/id.c
5 * PURPOSE: PCI Device Identification
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <pci.h>
12#include <stdio.h>
13
14#define NDEBUG
15#include <debug.h>
16
17/* FUNCTIONS ******************************************************************/
18
23{
25 ULONG TextLength;
27 ANSI_STRING MessageString;
30
31 /* Find the message identifier in the message table */
32 MessageString.Buffer = NULL;
34 11, // RT_MESSAGETABLE
37 &Entry);
38 if (!NT_SUCCESS(Status)) return NULL;
39
40 /* Check if the resource data is Unicode or ANSI */
42 {
43 /* Subtract one space for the end-of-message terminator */
44 TextLength = Entry->Length -
46 sizeof(WCHAR);
47
48 /* Grab the text */
49 Description = (PWCHAR)Entry->Text;
50
51 /* Validate valid message length, ending with a newline character */
52 ASSERT(TextLength > 1);
53 ASSERT(Description[TextLength / sizeof(WCHAR)] == L'\n');
54
55 /* Allocate the buffer to hold the message string */
56 Buffer = ExAllocatePoolWithTag(PagedPool, TextLength, 'BicP');
57 if (!Buffer) return NULL;
58
59 /* Copy the message, minus the newline character, and terminate it */
60 RtlCopyMemory(Buffer, Entry->Text, TextLength - 1);
61 Buffer[TextLength / sizeof(WCHAR)] = UNICODE_NULL;
62
63 /* Return the length to the caller, minus the terminating NULL */
64 if (Length) *Length = TextLength - 1;
65 }
66 else
67 {
68 /* Initialize the entry as a string */
69 RtlInitAnsiString(&MessageString, (PCHAR)Entry->Text);
70
71 /* Remove the newline character */
72 MessageString.Length -= sizeof(CHAR);
73
74 /* Convert it to Unicode */
76 Buffer = UnicodeString.Buffer;
77
78 /* Return the length to the caller */
79 if (Length) *Length = UnicodeString.Length;
80 }
81
82 /* Return the message buffer to the caller */
83 return Buffer;
84}
85
89 IN UCHAR SubClass)
90{
93
94 /* The message identifier in the table is encoded based on the PCI class */
95 Identifier = (BaseClass << 8) | SubClass;
96
97 /* Go grab the description message for this device */
99 if (!Message)
100 {
101 /* It wasn't found, allocate a buffer for a generic description */
102 Message = ExAllocatePoolWithTag(PagedPool, sizeof(L"PCI Device"), 'bicP');
103 if (Message) RtlCopyMemory(Message, L"PCI Device", sizeof(L"PCI Device"));
104 }
105
106 /* Return the description message */
107 return Message;
108}
109
110VOID
111NTAPI
113{
114 /* Initialize the sizes to zero and the pointer to the start of the buffer */
115 IdBuffer->TotalLength = 0;
116 IdBuffer->Count = 0;
117 IdBuffer->CharBuffer = IdBuffer->BufferData;
118}
119
120ULONG
123 IN PCCH Format,
124 ...)
125{
128 va_list va;
129
130 ASSERT(IdBuffer->Count < MAX_ANSI_STRINGS);
131
132 /* Do the actual string formatting into the character buffer */
133 va_start(va, Format);
134 vsprintf(IdBuffer->CharBuffer, Format, va);
135 va_end(va);
136
137 /* Initialize the ANSI_STRING that will hold this string buffer */
138 AnsiString = &IdBuffer->Strings[IdBuffer->Count];
139 RtlInitAnsiString(AnsiString, IdBuffer->CharBuffer);
140
141 /* Calculate the final size of the string, in Unicode */
143
144 /* Update hte buffer with the size,and update the character pointer */
145 IdBuffer->StringSize[IdBuffer->Count] = Size;
146 IdBuffer->TotalLength += Size;
147 Length = AnsiString->Length + sizeof(ANSI_NULL);
148 IdBuffer->CharBuffer += Length;
149
150 /* Move to the next string for next time */
151 IdBuffer->Count++;
152
153 /* Return the length */
154 return Length;
155}
156
157ULONG
160 IN PCCH Format,
161 ...)
162{
163 ULONG NextId, Size, Length, MaxLength;
165 va_list va;
166
167 ASSERT(IdBuffer->Count);
168
169 /* Choose the next static ANSI_STRING to use */
170 NextId = IdBuffer->Count - 1;
171
172 /* Max length is from the end of the buffer up until the current pointer */
173 MaxLength = (PCHAR)(IdBuffer + 1) - IdBuffer->CharBuffer;
174
175 /* Do the actual append, and return the length this string took */
176 va_start(va, Format);
177 Length = vsprintf(IdBuffer->CharBuffer - 1, Format, va);
178 va_end(va);
179 ASSERT(Length < MaxLength);
180
181 /* Select the static ANSI_STRING, and update its length information */
182 AnsiString = &IdBuffer->Strings[NextId];
183 AnsiString->Length += Length;
184 AnsiString->MaximumLength += Length;
185
186 /* Calculate the final size of the string, in Unicode */
188
189 /* Update the buffer with the size, and update the character pointer */
190 IdBuffer->StringSize[NextId] = Size;
191 IdBuffer->TotalLength += Size;
192 IdBuffer->CharBuffer += Length;
193
194 /* Return the size */
195 return Size;
196}
197
199NTAPI
203{
204 ULONG SubsysId;
205 CHAR VendorString[22];
207 PPCI_FDO_EXTENSION ParentExtension;
209 ULONG i, Size;
211 PANSI_STRING NextString;
213 PCI_ID_BUFFER IdBuffer;
214 PAGED_CODE();
215
216 /* Assume failure */
218 *Buffer = NULL;
219
220 /* Start with the genric vendor string, which is the vendor ID + device ID */
221 sprintf(VendorString,
222 "PCI\\VEN_%04X&DEV_%04X",
223 DeviceExtension->VendorId,
224 DeviceExtension->DeviceId);
225
226 /* Initialize the PCI ID Buffer */
227 PciInitIdBuffer(&IdBuffer);
228
229 /* Build the subsystem ID as shown in PCI ID Strings */
230 SubsysId = DeviceExtension->SubsystemVendorId | (DeviceExtension->SubsystemId << 16);
231
232 /* Check what the caller is requesting */
233 switch (QueryType)
234 {
235 case BusQueryDeviceID:
236
237 /* A single ID, the vendor string + the revision ID */
238 PciIdPrintf(&IdBuffer,
239 "%s&SUBSYS_%08X&REV_%02X",
240 VendorString,
241 SubsysId,
242 DeviceExtension->RevisionId);
243 break;
244
246
247 /* First the vendor string + the subsystem ID + the revision ID */
248 PciIdPrintf(&IdBuffer,
249 "%s&SUBSYS_%08X&REV_%02X",
250 VendorString,
251 SubsysId,
252 DeviceExtension->RevisionId);
253
254 /* Next, without the revision */
255 PciIdPrintf(&IdBuffer,
256 "%s&SUBSYS_%08X",
257 VendorString,
258 SubsysId);
259
260 /* Next, the vendor string + the base class + sub class + progif */
261 PciIdPrintf(&IdBuffer,
262 "%s&CC_%02X%02X%02X",
263 VendorString,
264 DeviceExtension->BaseClass,
265 DeviceExtension->SubClass,
266 DeviceExtension->ProgIf);
267
268 /* Next, without the progif */
269 PciIdPrintf(&IdBuffer,
270 "%s&CC_%02X%02X",
271 VendorString,
272 DeviceExtension->BaseClass,
273 DeviceExtension->SubClass);
274
275 /* And finally, a terminator */
276 PciIdPrintf(&IdBuffer, "\0");
277 break;
278
280
281 /* First, the vendor + revision ID only */
282 PciIdPrintf(&IdBuffer,
283 "%s&REV_%02X",
284 VendorString,
285 DeviceExtension->RevisionId);
286
287 /* Next, the vendor string alone */
288 PciIdPrintf(&IdBuffer, "%s", VendorString);
289
290 /* Next, the vendor ID + the base class + the sub class + progif */
291 PciIdPrintf(&IdBuffer,
292 "PCI\\VEN_%04X&CC_%02X%02X%02X",
293 DeviceExtension->VendorId,
294 DeviceExtension->BaseClass,
295 DeviceExtension->SubClass,
296 DeviceExtension->ProgIf);
297
298 /* Now without the progif */
299 PciIdPrintf(&IdBuffer,
300 "PCI\\VEN_%04X&CC_%02X%02X",
301 DeviceExtension->VendorId,
302 DeviceExtension->BaseClass,
303 DeviceExtension->SubClass);
304
305 /* And then just the vendor ID itself */
306 PciIdPrintf(&IdBuffer,
307 "PCI\\VEN_%04X",
308 DeviceExtension->VendorId);
309
310 /* Then the base class + subclass + progif, without any vendor */
311 PciIdPrintf(&IdBuffer,
312 "PCI\\CC_%02X%02X%02X",
313 DeviceExtension->BaseClass,
314 DeviceExtension->SubClass,
315 DeviceExtension->ProgIf);
316
317 /* Next, without the progif */
318 PciIdPrintf(&IdBuffer,
319 "PCI\\CC_%02X%02X",
320 DeviceExtension->BaseClass,
321 DeviceExtension->SubClass);
322
323 /* And finally, a terminator */
324 PciIdPrintf(&IdBuffer, "\0");
325 break;
326
328
329 /* Start with a terminator */
330 PciIdPrintf(&IdBuffer, "\0");
331
332 /* And then encode the device and function number */
333 PciIdPrintfAppend(&IdBuffer,
334 "%02X",
335 (DeviceExtension->Slot.u.bits.DeviceNumber << 3) |
336 DeviceExtension->Slot.u.bits.FunctionNumber);
337
338 /* Loop every parent until the root */
339 ParentExtension = DeviceExtension->ParentFdoExtension;
340 while (!PCI_IS_ROOT_FDO(ParentExtension))
341 {
342 /* And encode the parent's device and function number as well */
344 PciIdPrintfAppend(&IdBuffer,
345 "%02X",
346 (PdoExtension->Slot.u.bits.DeviceNumber << 3) |
347 PdoExtension->Slot.u.bits.FunctionNumber);
348 }
349 break;
350
351 default:
352
353 /* Unknown query type */
354 DPRINT1("PciQueryId expected ID type = %d\n", QueryType);
356 }
357
358 /* Something should've been generated if this has been reached */
359 ASSERT(IdBuffer.Count > 0);
360
361 /* Allocate the final string buffer to hold the ID */
364
365 /* Build the UNICODE_STRING structure for it */
366 DPRINT1("PciQueryId(%d)\n", QueryType);
369
370 /* Loop every ID in the buffer */
371 for (i = 0; i < IdBuffer.Count; i++)
372 {
373 /* Select the ANSI_STRING for the ID */
374 NextString = &IdBuffer.Strings[i];
375 DPRINT1(" <- \"%s\"\n", NextString->Buffer);
376
377 /* Convert it to a UNICODE_STRING */
380
381 /* Add it into the final destination buffer */
382 Size = IdBuffer.StringSize[i];
384 DestinationString.Buffer += (Size / sizeof(WCHAR));
385 }
386
387 /* Return the buffer to the caller and return status (should be success) */
389 return Status;
390}
391
393NTAPI
396 IN ULONG Locale,
398{
399 PWCHAR MessageBuffer, LocationBuffer;
402
404
405 /* Check what the caller is requesting */
406 switch (QueryType)
407 {
409
410 /* Get the message from the resource section */
411 MessageBuffer = PciGetDeviceDescriptionMessage(PdoExtension->BaseClass,
412 PdoExtension->SubClass);
413
414 /* Return it to the caller, and select proper status code */
415 *Buffer = MessageBuffer;
416 Status = MessageBuffer ? STATUS_SUCCESS : STATUS_NOT_SUPPORTED;
417 break;
418
420
421 /* Get the message from the resource section */
422 MessageBuffer = PciGetDescriptionMessage(0x10000, &Length);
423 if (!MessageBuffer)
424 {
425 /* It should be there, but fail if it wasn't found for some reason */
427 break;
428 }
429
430 /* Add space for a null-terminator, and allocate the buffer */
431 Length += 2 * sizeof(UNICODE_NULL);
432 LocationBuffer = ExAllocatePoolWithTag(PagedPool,
433 Length * sizeof(WCHAR),
434 'BicP');
435 *Buffer = LocationBuffer;
436
437 /* Check if the allocation succeeded */
438 if (LocationBuffer)
439 {
440 /* Build the location string based on bus, function, and device */
441 swprintf(LocationBuffer,
442 MessageBuffer,
443 PdoExtension->ParentFdoExtension->BaseBus,
444 PdoExtension->Slot.u.bits.FunctionNumber,
445 PdoExtension->Slot.u.bits.DeviceNumber);
446 }
447
448 /* Free the original string from the resource section */
449 ExFreePoolWithTag(MessageBuffer, 0);
450
451 /* Select the correct status */
453 break;
454
455 default:
456
457 /* Anything else is unsupported */
459 break;
460 }
461
462 /* Return whether or not a device text string was indeed found */
463 return Status;
464}
465
466/* EOF */
#define PAGED_CODE()
#define __cdecl
Definition: accygwin.h:79
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
@ Identifier
Definition: asmpp.cpp:95
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define CHAR(Char)
Definition: bufpool.h:45
char * Text
Definition: combotst.c:136
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#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:33
static const WCHAR Description[]
Definition: oid.c:1266
#define swprintf
Definition: precomp.h:40
static const WCHAR Message[]
Definition: register.c:74
@ AnsiString
Definition: dnslib.h:19
PDRIVER_OBJECT PciDriverObject
Definition: init.c:19
#define MAX_ANSI_STRINGS
Definition: pci.h:87
#define PCI_IS_ROOT_FDO(x)
Definition: pci.h:32
@ PdoExtension
Definition: precomp.h:49
#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
PWCHAR NTAPI PciGetDescriptionMessage(IN ULONG Identifier, OUT PULONG Length)
Definition: id.c:21
NTSTATUS NTAPI PciQueryId(IN PPCI_PDO_EXTENSION DeviceExtension, IN BUS_QUERY_ID_TYPE QueryType, OUT PWCHAR *Buffer)
Definition: id.c:200
PWCHAR NTAPI PciGetDeviceDescriptionMessage(IN UCHAR BaseClass, IN UCHAR SubClass)
Definition: id.c:88
ULONG __cdecl PciIdPrintfAppend(IN PPCI_ID_BUFFER IdBuffer, IN PCCH Format,...)
Definition: id.c:159
VOID NTAPI PciInitIdBuffer(IN PPCI_ID_BUFFER IdBuffer)
Definition: id.c:112
NTSTATUS NTAPI PciQueryDeviceText(IN PPCI_PDO_EXTENSION PdoExtension, IN DEVICE_TEXT_TYPE QueryType, IN ULONG Locale, OUT PWCHAR *Buffer)
Definition: id.c:394
ULONG __cdecl PciIdPrintf(IN PPCI_ID_BUFFER IdBuffer, IN PCCH Format,...)
Definition: id.c:122
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define sprintf(buf, format,...)
Definition: sprintf.c:55
_Out_ _Inout_ POEM_STRING DestinationString
Definition: rtlfuncs.h:1921
NTSYSAPI NTSTATUS NTAPI RtlFindMessage(_In_ PVOID BaseAddress, _In_ ULONG Type, _In_ ULONG Language, _In_ ULONG MessageId, _Out_ PMESSAGE_RESOURCE_ENTRY *MessageResourceEntry)
#define MESSAGE_RESOURCE_UNICODE
Definition: rtltypes.h:351
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define RtlAnsiStringToUnicodeSize(STRING)
Definition: nt_native.h:404
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define ANSI_NULL
CONST CHAR * PCCH
Definition: ntbasedef.h:400
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
_Must_inspect_result_ _In_ KTMOBJECT_TYPE QueryType
Definition: nttmapi.h:404
#define L(x)
Definition: ntvdm.h:50
#define LANG_NEUTRAL
Definition: nls.h:22
#define STATUS_SUCCESS
Definition: shellext.h:65
base of all file and directory entries
Definition: entries.h:83
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PVOID DriverStart
Definition: iotypes.h:2279
Definition: rtltypes.h:1896
PDEVICE_OBJECT PhysicalDeviceObject
Definition: pci.h:200
struct _PCI_FDO_EXTENSION * ParentFdoExtension
Definition: pci.h:206
ULONG Count
Definition: pci.h:426
ULONG StringSize[MAX_ANSI_STRINGS]
Definition: pci.h:428
ANSI_STRING Strings[MAX_ANSI_STRINGS]
Definition: pci.h:427
ULONG TotalLength
Definition: pci.h:429
void * Buffer
Definition: sprintf.c:453
unsigned short MaximumLength
Definition: sprintf.c:452
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
enum _BUS_QUERY_ID_TYPE BUS_QUERY_ID_TYPE
@ DeviceTextLocationInformation
Definition: iotypes.h:2946
@ DeviceTextDescription
Definition: iotypes.h:2945
enum _DEVICE_TEXT_TYPE DEVICE_TEXT_TYPE
@ BusQueryCompatibleIDs
Definition: iotypes.h:2938
@ BusQueryInstanceID
Definition: iotypes.h:2939
@ BusQueryDeviceID
Definition: iotypes.h:2936
@ BusQueryHardwareIDs
Definition: iotypes.h:2937
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175