ReactOS  0.4.15-dev-5606-gf34e425
classinst.c File Reference
#include "precomp.h"
#include <debug.h>
Include dependency graph for classinst.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

DWORD WINAPI ComputerClassInstaller (IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 
DWORD WINAPI CriticalDeviceCoInstaller (IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN OUT PCOINSTALLER_CONTEXT_DATA Context)
 
DWORD WINAPI DeviceBayClassInstaller (IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 
DWORD WINAPI EisaUpHalCoInstaller (IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN OUT PCOINSTALLER_CONTEXT_DATA Context)
 
DWORD WINAPI HdcClassInstaller (IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 
DWORD WINAPI KeyboardClassInstaller (IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 
DWORD WINAPI MouseClassInstaller (IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 
DWORD WINAPI NtApmClassInstaller (IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 
DWORD WINAPI ScsiClassInstaller (IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 
DWORD WINAPI StorageCoInstaller (IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN OUT PCOINSTALLER_CONTEXT_DATA Context)
 
DWORD WINAPI TapeClassInstaller (IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 
DWORD WINAPI VolumeClassInstaller (IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 11 of file classinst.c.

Function Documentation

◆ ComputerClassInstaller()

DWORD WINAPI ComputerClassInstaller ( IN DI_FUNCTION  InstallFunction,
IN HDEVINFO  DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL 
)

Definition at line 19 of file classinst.c.

23 {
24  switch (InstallFunction)
25  {
26  default:
27  DPRINT1("Install function %u ignored\n", InstallFunction);
28  return ERROR_DI_DO_DEFAULT;
29  }
30 }
#define DPRINT1
Definition: precomp.h:8
#define ERROR_DI_DO_DEFAULT
Definition: setupapi.h:310

◆ CriticalDeviceCoInstaller()

DWORD WINAPI CriticalDeviceCoInstaller ( IN DI_FUNCTION  InstallFunction,
IN HDEVINFO  DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
IN OUT PCOINSTALLER_CONTEXT_DATA  Context 
)

Definition at line 38 of file classinst.c.

43 {
44  WCHAR szDeviceId[256];
45  WCHAR szServiceName[256];
46  WCHAR szClassGUID[64];
47  DWORD dwRequiredSize;
48  HKEY hDriverKey = NULL;
49  HKEY hDatabaseKey = NULL, hDeviceKey = NULL;
50  DWORD dwDisposition;
51  PWSTR Ptr;
52  DWORD dwError = ERROR_SUCCESS;
53 
54  DPRINT("CriticalDeviceCoInstaller(%lu %p %p %p)\n",
55  InstallFunction, DeviceInfoSet, DeviceInfoData, Context);
56 
57  if (InstallFunction != DIF_INSTALLDEVICE)
58  return ERROR_SUCCESS;
59 
60  /* Get the MatchingDeviceId property */
64  0,
65  DIREG_DRV,
66  KEY_READ);
67  if (hDriverKey == INVALID_HANDLE_VALUE)
68  {
69  if (Context->PostProcessing)
70  {
71  dwError = GetLastError();
72  DPRINT1("Failed to open the driver key! (Error %lu)\n", dwError);
73  goto done;
74  }
75  else
76  {
77  DPRINT("Failed to open the driver key! Postprocessing required!\n");
79  }
80  }
81 
82  dwRequiredSize = sizeof(szDeviceId);
83  dwError = RegQueryValueExW(hDriverKey,
84  L"MatchingDeviceId",
85  NULL,
86  NULL,
88  &dwRequiredSize);
89  RegCloseKey(hDriverKey);
90  if (dwError != ERROR_SUCCESS)
91  {
92  if (Context->PostProcessing)
93  {
94  dwError = GetLastError();
95  DPRINT1("Failed to read the MatchingDeviceId value! (Error %lu)\n", dwError);
96  goto done;
97  }
98  else
99  {
100  DPRINT("Failed to read the MatchingDeviceId value! Postprocessing required!\n");
102  }
103  }
104 
105  DPRINT("MatchingDeviceId: %S\n", szDeviceId);
106 
107  /* Get the ClassGUID property */
108  dwRequiredSize = 0;
112  NULL,
113  (PBYTE)szClassGUID,
114  sizeof(szClassGUID),
115  &dwRequiredSize))
116  {
117  if (Context->PostProcessing)
118  {
119  dwError = GetLastError();
120  DPRINT1("Failed to read the ClassGUID! (Error %lu)\n", dwError);
121  goto done;
122  }
123  else
124  {
125  DPRINT("Failed to read the ClassGUID! Postprocessing required!\n");
127  }
128  }
129 
130  DPRINT("ClassGUID %S\n", szClassGUID);
131 
132  /* Get the Service property (optional) */
133  dwRequiredSize = 0;
137  NULL,
138  (PBYTE)szServiceName,
139  sizeof(szServiceName),
140  &dwRequiredSize))
141  {
142  if (Context->PostProcessing)
143  {
144  dwError = GetLastError();
145  if (dwError != ERROR_FILE_NOT_FOUND)
146  {
147  DPRINT1("Failed to read the Service name! (Error %lu)\n", dwError);
148  goto done;
149  }
150  else
151  {
152  szServiceName[0] = UNICODE_NULL;
153  dwError = ERROR_SUCCESS;
154  }
155  }
156  else
157  {
158  DPRINT("Failed to read the Service name! Postprocessing required!\n");
160  }
161  }
162 
163  DPRINT("Service %S\n", szServiceName);
164 
165  /* Replace the first backslash by a number sign */
166  Ptr = wcschr(szDeviceId, L'\\');
167  if (Ptr != NULL)
168  {
169  *Ptr = L'#';
170 
171  /* Terminate the device id at the second backslash */
172  Ptr = wcschr(Ptr, L'\\');
173  if (Ptr != NULL)
174  *Ptr = UNICODE_NULL;
175  }
176 
177  DPRINT("DeviceId: %S\n", szDeviceId);
178 
179  /* Open the critical device database key */
181  L"SYSTEM\\CurrentControlSet\\Control\\CriticalDeviceDatabase",
182  0,
183  KEY_WRITE,
184  &hDatabaseKey);
185  if (dwError != ERROR_SUCCESS)
186  {
187  DPRINT1("RegOpenKeyExW failed (Error %lu)\n", dwError);
188  goto done;
189  }
190 
191  /* Create a new key for the device */
192  dwError = RegCreateKeyExW(hDatabaseKey,
193  szDeviceId,
194  0,
195  NULL,
197  KEY_WRITE,
198  NULL,
199  &hDeviceKey,
200  &dwDisposition);
201  if (dwError != ERROR_SUCCESS)
202  {
203  DPRINT1("RegCreateKeyExW failed (Error %lu)\n", dwError);
204  goto done;
205  }
206 
207  /* Set the ClassGUID value */
208  dwError = RegSetValueExW(hDeviceKey,
209  L"ClassGUID",
210  0,
211  REG_SZ,
212  (PBYTE)szClassGUID,
213  (wcslen(szClassGUID) + 1) * sizeof(WCHAR));
214  if (dwError != ERROR_SUCCESS)
215  {
216  DPRINT1("RegSetValueExW failed (Error %lu)\n", dwError);
217  goto done;
218  }
219 
220  /* If available, set the Service value */
221  if (szServiceName[0] != UNICODE_NULL)
222  {
223  dwError = RegSetValueExW(hDeviceKey,
224  L"Service",
225  0,
226  REG_SZ,
227  (PBYTE)szServiceName,
228  (wcslen(szServiceName) + 1) * sizeof(WCHAR));
229  if (dwError != ERROR_SUCCESS)
230  {
231  DPRINT1("RegSetValueExW failed (Error %lu)\n", dwError);
232  goto done;
233  }
234  }
235 
236 done:
237  if (hDeviceKey != NULL)
238  RegCloseKey(hDeviceKey);
239 
240  if (hDatabaseKey != NULL)
241  RegCloseKey(hDatabaseKey);
242 
243  DPRINT("CriticalDeviceCoInstaller() done (Error %lu)\n", dwError);
244 
245  return dwError;
246 }
#define ERROR_SUCCESS
Definition: deptool.c:10
static const WCHAR szDeviceId[]
Definition: provider.c:60
#define KEY_READ
Definition: nt_native.h:1023
uint16_t * PWSTR
Definition: typedefs.h:56
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize)
Definition: devinst.c:3224
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
#define SPDRP_CLASSGUID
Definition: setupapi.h:515
#define L(x)
Definition: ntvdm.h:50
#define UNICODE_NULL
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define DIF_INSTALLDEVICE
Definition: setupapi.h:121
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4900
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4121
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData
Definition: setupapi.h:1528
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SPDRP_SERVICE
Definition: setupapi.h:511
HKEY WINAPI SetupDiOpenDevRegKey(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType, REGSAM samDesired)
Definition: devinst.c:5934
#define DICS_FLAG_GLOBAL
Definition: setupapi.h:113
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
#define DIREG_DRV
Definition: setupapi.h:182
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
#define DPRINT
Definition: sndvol32.h:71
#define ERROR_DI_POSTPROCESSING_REQUIRED
Definition: setupapi.h:334
BYTE * PBYTE
Definition: pedump.c:66
#define RegCloseKey(hKey)
Definition: registry.h:47
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22

◆ DeviceBayClassInstaller()

DWORD WINAPI DeviceBayClassInstaller ( IN DI_FUNCTION  InstallFunction,
IN HDEVINFO  DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL 
)

Definition at line 254 of file classinst.c.

258 {
259  switch (InstallFunction)
260  {
261  default:
262  DPRINT("Install function %u ignored\n", InstallFunction);
263  return ERROR_DI_DO_DEFAULT;
264  }
265 }
#define ERROR_DI_DO_DEFAULT
Definition: setupapi.h:310
#define DPRINT
Definition: sndvol32.h:71

◆ EisaUpHalCoInstaller()

DWORD WINAPI EisaUpHalCoInstaller ( IN DI_FUNCTION  InstallFunction,
IN HDEVINFO  DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
IN OUT PCOINSTALLER_CONTEXT_DATA  Context 
)

Definition at line 273 of file classinst.c.

278 {
279  switch (InstallFunction)
280  {
281  default:
282  DPRINT1("Install function %u ignored\n", InstallFunction);
283  return ERROR_SUCCESS;
284  }
285 }
#define ERROR_SUCCESS
Definition: deptool.c:10
#define DPRINT1
Definition: precomp.h:8

◆ HdcClassInstaller()

DWORD WINAPI HdcClassInstaller ( IN DI_FUNCTION  InstallFunction,
IN HDEVINFO  DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL 
)

Definition at line 293 of file classinst.c.

297 {
298  DPRINT("HdcClassInstaller()\n");
299  return ERROR_DI_DO_DEFAULT;
300 }
#define ERROR_DI_DO_DEFAULT
Definition: setupapi.h:310
#define DPRINT
Definition: sndvol32.h:71

◆ KeyboardClassInstaller()

DWORD WINAPI KeyboardClassInstaller ( IN DI_FUNCTION  InstallFunction,
IN HDEVINFO  DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL 
)

Definition at line 308 of file classinst.c.

312 {
313  switch (InstallFunction)
314  {
315  default:
316  DPRINT("Install function %u ignored\n", InstallFunction);
317  return ERROR_DI_DO_DEFAULT;
318  }
319 }
#define ERROR_DI_DO_DEFAULT
Definition: setupapi.h:310
#define DPRINT
Definition: sndvol32.h:71

◆ MouseClassInstaller()

DWORD WINAPI MouseClassInstaller ( IN DI_FUNCTION  InstallFunction,
IN HDEVINFO  DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL 
)

Definition at line 327 of file classinst.c.

331 {
332  switch (InstallFunction)
333  {
334  default:
335  DPRINT("Install function %u ignored\n", InstallFunction);
336  return ERROR_DI_DO_DEFAULT;
337  }
338 }
#define ERROR_DI_DO_DEFAULT
Definition: setupapi.h:310
#define DPRINT
Definition: sndvol32.h:71

◆ NtApmClassInstaller()

DWORD WINAPI NtApmClassInstaller ( IN DI_FUNCTION  InstallFunction,
IN HDEVINFO  DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL 
)

Definition at line 346 of file classinst.c.

350 {
351  switch (InstallFunction)
352  {
353  default:
354  DPRINT("Install function %u ignored\n", InstallFunction);
355  return ERROR_DI_DO_DEFAULT;
356  }
357 }
#define ERROR_DI_DO_DEFAULT
Definition: setupapi.h:310
#define DPRINT
Definition: sndvol32.h:71

◆ ScsiClassInstaller()

DWORD WINAPI ScsiClassInstaller ( IN DI_FUNCTION  InstallFunction,
IN HDEVINFO  DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL 
)

Definition at line 365 of file classinst.c.

369 {
370  switch (InstallFunction)
371  {
372  default:
373  DPRINT("Install function %u ignored\n", InstallFunction);
374  return ERROR_DI_DO_DEFAULT;
375  }
376 }
#define ERROR_DI_DO_DEFAULT
Definition: setupapi.h:310
#define DPRINT
Definition: sndvol32.h:71

◆ StorageCoInstaller()

DWORD WINAPI StorageCoInstaller ( IN DI_FUNCTION  InstallFunction,
IN HDEVINFO  DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
IN OUT PCOINSTALLER_CONTEXT_DATA  Context 
)

Definition at line 384 of file classinst.c.

389 {
390  ULONG ulStatus, ulProblem;
391  DWORD dwBufferSize = 0;
392  PWSTR pszDeviceDescription;
393  CONFIGRET ret;
394 
395  DPRINT("StorageCoInstaller(%u %p %p %p)\n",
396  InstallFunction, DeviceInfoSet, DeviceInfoData, Context);
397 
398  if (InstallFunction != DIF_INSTALLDEVICE)
399  return ERROR_SUCCESS;
400 
401  if (Context->PostProcessing)
402  {
403  if (Context->PrivateData != NULL)
404  {
405  pszDeviceDescription = (PWSTR)Context->PrivateData;
406 
407  /* Store the device description as the friendly name */
411  (PBYTE)pszDeviceDescription,
412  (wcslen(pszDeviceDescription) + 1) * sizeof(WCHAR));
413 
414  /* Free the device description */
415  HeapFree(GetProcessHeap(), 0, Context->PrivateData);
416  Context->PrivateData = NULL;
417  }
418  }
419  else
420  {
421  if (DeviceInfoData == NULL)
422  return ERROR_SUCCESS;
423 
424  ret = CM_Get_DevNode_Status(&ulStatus, &ulProblem, DeviceInfoData->DevInst, 0);
425  if (ret != CR_SUCCESS)
426  return ERROR_SUCCESS;
427 
428  if (ulStatus & DN_ROOT_ENUMERATED)
429  return ERROR_SUCCESS;
430 
431  /* Get the device description size */
435  NULL,
436  NULL,
437  0,
438  &dwBufferSize);
439  if (dwBufferSize == 0)
440  return ERROR_SUCCESS;
441 
442  /* Allocate the device description buffer */
443  pszDeviceDescription = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
444  if (pszDeviceDescription == NULL)
445  return ERROR_SUCCESS;
446 
447  /* Get the device description */
451  NULL,
452  (PBYTE)pszDeviceDescription,
453  dwBufferSize,
454  &dwBufferSize);
455 
456  Context->PrivateData = (PVOID)pszDeviceDescription;
458  }
459 
460  return ERROR_SUCCESS;
461 }
#define ERROR_SUCCESS
Definition: deptool.c:10
#define DN_ROOT_ENUMERATED
Definition: cfg.h:118
uint16_t * PWSTR
Definition: typedefs.h:56
BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize)
Definition: devinst.c:3224
#define CR_SUCCESS
Definition: cfgmgr32.h:842
void * PVOID
Definition: retypes.h:9
#define DIF_INSTALLDEVICE
Definition: setupapi.h:121
#define GetProcessHeap()
Definition: compat.h:736
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData
Definition: setupapi.h:1528
#define SPDRP_FRIENDLYNAME
Definition: setupapi.h:519
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
#define SPDRP_DEVICEDESC
Definition: setupapi.h:507
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
RETURN_TYPE CONFIGRET
Definition: cfgmgr32.h:74
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
CONFIGRET WINAPI CM_Get_DevNode_Status(_Out_ PULONG pulStatus, _Out_ PULONG pulProblemNumber, _In_ DEVINST dnDevInst, _In_ ULONG ulFlags)
Definition: cfgmgr.c:3573
BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, const BYTE *PropertyBuffer, DWORD PropertyBufferSize)
Definition: devinst.c:3452
unsigned int ULONG
Definition: retypes.h:1
#define DPRINT
Definition: sndvol32.h:71
#define ERROR_DI_POSTPROCESSING_REQUIRED
Definition: setupapi.h:334
BYTE * PBYTE
Definition: pedump.c:66
#define HeapFree(x, y, z)
Definition: compat.h:735

◆ TapeClassInstaller()

DWORD WINAPI TapeClassInstaller ( IN DI_FUNCTION  InstallFunction,
IN HDEVINFO  DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL 
)

Definition at line 469 of file classinst.c.

473 {
474  DPRINT("TapeClassInstaller()\n");
475  return ERROR_DI_DO_DEFAULT;
476 }
#define ERROR_DI_DO_DEFAULT
Definition: setupapi.h:310
#define DPRINT
Definition: sndvol32.h:71

◆ VolumeClassInstaller()

DWORD WINAPI VolumeClassInstaller ( IN DI_FUNCTION  InstallFunction,
IN HDEVINFO  DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL 
)

Definition at line 484 of file classinst.c.

488 {
489  DPRINT("VolumeClassInstaller()\n");
490  return ERROR_DI_DO_DEFAULT;
491 }
#define ERROR_DI_DO_DEFAULT
Definition: setupapi.h:310
#define DPRINT
Definition: sndvol32.h:71