]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.c
SecurityPkg: Tcg2ConfigDxe: Remove duplicate local variable
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Config / Tcg2ConfigImpl.c
CommitLineData
1abfa4ce
JY
1/** @file\r
2 HII Config Access protocol implementation of TCG2 configuration module.\r
3 NOTE: This module is only for reference only, each platform should have its own setup page.\r
4\r
a6e0e994 5Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
1abfa4ce
JY
6This program and the accompanying materials \r
7are licensed and made available under the terms and conditions of the BSD License \r
8which accompanies this distribution. The full text of the license may be found at \r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "Tcg2ConfigImpl.h"\r
17#include <Library/PcdLib.h>\r
18#include <Library/Tpm2CommandLib.h>\r
518b6f65 19#include <Library/IoLib.h>\r
1abfa4ce
JY
20#include <Guid/TpmInstance.h>\r
21\r
518b6f65
JY
22#include <IndustryStandard/TpmPtp.h>\r
23\r
1abfa4ce
JY
24#define EFI_TCG2_EVENT_LOG_FORMAT_ALL (EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)\r
25\r
26TPM_INSTANCE_ID mTpmInstanceId[TPM_DEVICE_MAX + 1] = TPM_INSTANCE_ID_LIST;\r
27\r
28TCG2_CONFIG_PRIVATE_DATA *mTcg2ConfigPrivateDate;\r
29TCG2_CONFIG_PRIVATE_DATA mTcg2ConfigPrivateDateTemplate = {\r
30 TCG2_CONFIG_PRIVATE_DATA_SIGNATURE,\r
31 {\r
32 Tcg2ExtractConfig,\r
33 Tcg2RouteConfig,\r
34 Tcg2Callback\r
35 }\r
36};\r
37\r
38HII_VENDOR_DEVICE_PATH mTcg2HiiVendorDevicePath = {\r
39 {\r
40 {\r
41 HARDWARE_DEVICE_PATH,\r
42 HW_VENDOR_DP,\r
43 {\r
44 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
45 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
46 }\r
47 },\r
48 TCG2_CONFIG_FORM_SET_GUID\r
49 },\r
50 {\r
51 END_DEVICE_PATH_TYPE,\r
52 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
53 { \r
54 (UINT8) (END_DEVICE_PATH_LENGTH),\r
55 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
56 }\r
57 }\r
58};\r
59\r
60UINT8 mCurrentPpRequest;\r
61\r
518b6f65
JY
62/**\r
63 Return PTP interface type.\r
64\r
65 @param[in] Register Pointer to PTP register.\r
66\r
67 @return PTP interface type.\r
68**/\r
69UINT8\r
70GetPtpInterface (\r
71 IN VOID *Register\r
72 )\r
73{\r
74 PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;\r
75 PTP_FIFO_INTERFACE_CAPABILITY InterfaceCapability;\r
76\r
77 //\r
78 // Check interface id\r
79 //\r
80 InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);\r
81 InterfaceCapability.Uint32 = MmioRead32 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->InterfaceCapability);\r
82\r
83 if ((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_CRB) &&\r
84 (InterfaceId.Bits.InterfaceVersion == PTP_INTERFACE_IDENTIFIER_INTERFACE_VERSION_CRB) &&\r
85 (InterfaceId.Bits.CapCRB != 0)) {\r
86 return TPM_DEVICE_INTERFACE_PTP_CRB;\r
87 }\r
88 if ((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_FIFO) &&\r
89 (InterfaceId.Bits.InterfaceVersion == PTP_INTERFACE_IDENTIFIER_INTERFACE_VERSION_FIFO) &&\r
90 (InterfaceId.Bits.CapFIFO != 0) &&\r
91 (InterfaceCapability.Bits.InterfaceVersion == INTERFACE_CAPABILITY_INTERFACE_VERSION_PTP)) {\r
92 return TPM_DEVICE_INTERFACE_PTP_FIFO;\r
93 }\r
94 return TPM_DEVICE_INTERFACE_TIS;\r
95}\r
96\r
97/**\r
98 Return if PTP CRB is supported.\r
99\r
100 @param[in] Register Pointer to PTP register.\r
101 \r
102 @retval TRUE PTP CRB is supported.\r
103 @retval FALSE PTP CRB is unsupported.\r
104**/\r
105BOOLEAN\r
106IsPtpCrbSupported (\r
107 IN VOID *Register\r
108 )\r
109{\r
110 PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;\r
111\r
112 //\r
113 // Check interface id\r
114 //\r
115 InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);\r
116\r
117 if (((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_CRB) ||\r
118 (InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_FIFO)) &&\r
119 (InterfaceId.Bits.CapCRB != 0)) {\r
120 return TRUE;\r
121 }\r
122 return FALSE;\r
123}\r
124\r
125/**\r
126 Return if PTP FIFO is supported.\r
127\r
128 @param[in] Register Pointer to PTP register.\r
129 \r
130 @retval TRUE PTP FIFO is supported.\r
131 @retval FALSE PTP FIFO is unsupported.\r
132**/\r
133BOOLEAN\r
134IsPtpFifoSupported (\r
135 IN VOID *Register\r
136 )\r
137{\r
138 PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;\r
139\r
140 //\r
141 // Check interface id\r
142 //\r
143 InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);\r
144\r
145 if (((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_CRB) ||\r
146 (InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_FIFO)) &&\r
147 (InterfaceId.Bits.CapFIFO != 0)) {\r
148 return TRUE;\r
149 }\r
150 return FALSE;\r
151}\r
152\r
153/**\r
154 Set PTP interface type.\r
155\r
156 @param[in] Register Pointer to PTP register.\r
157 @param[in] PtpInterface PTP interface type.\r
158 \r
159 @retval EFI_SUCCESS PTP interface type is set.\r
160 @retval EFI_INVALID_PARAMETER PTP interface type is invalid.\r
161 @retval EFI_UNSUPPORTED PTP interface type is unsupported.\r
162 @retval EFI_WRITE_PROTECTED PTP interface is locked.\r
163**/\r
164EFI_STATUS\r
165SetPtpInterface (\r
166 IN VOID *Register,\r
167 IN UINT8 PtpInterface\r
168 )\r
169{\r
170 UINT8 PtpInterfaceCurrent;\r
171 PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;\r
172\r
173 PtpInterfaceCurrent = GetPtpInterface (Register);\r
174 if ((PtpInterfaceCurrent != TPM_DEVICE_INTERFACE_PTP_FIFO) && \r
175 (PtpInterfaceCurrent != TPM_DEVICE_INTERFACE_PTP_CRB)) {\r
176 return EFI_UNSUPPORTED;\r
177 }\r
178 InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);\r
179 if (InterfaceId.Bits.IntfSelLock != 0) {\r
180 return EFI_WRITE_PROTECTED;\r
181 }\r
182\r
183 switch (PtpInterface) {\r
184 case TPM_DEVICE_INTERFACE_PTP_FIFO:\r
185 if (InterfaceId.Bits.CapFIFO == 0) {\r
186 return EFI_UNSUPPORTED;\r
187 }\r
188 InterfaceId.Bits.InterfaceSelector = PTP_INTERFACE_IDENTIFIER_INTERFACE_SELECTOR_FIFO;\r
189 MmioWrite32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId, InterfaceId.Uint32);\r
190 return EFI_SUCCESS;\r
191 case TPM_DEVICE_INTERFACE_PTP_CRB:\r
192 if (InterfaceId.Bits.CapCRB == 0) {\r
193 return EFI_UNSUPPORTED;\r
194 }\r
195 InterfaceId.Bits.InterfaceSelector = PTP_INTERFACE_IDENTIFIER_INTERFACE_SELECTOR_CRB;\r
196 MmioWrite32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId, InterfaceId.Uint32);\r
197 return EFI_SUCCESS;\r
198 default:\r
199 return EFI_INVALID_PARAMETER;\r
200 }\r
201}\r
202\r
1abfa4ce
JY
203/**\r
204 This function allows a caller to extract the current configuration for one\r
205 or more named elements from the target driver.\r
206\r
207 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
208 @param[in] Request A null-terminated Unicode string in\r
209 <ConfigRequest> format.\r
210 @param[out] Progress On return, points to a character in the Request\r
211 string. Points to the string's null terminator if\r
212 request was successful. Points to the most recent\r
213 '&' before the first failing name/value pair (or\r
214 the beginning of the string if the failure is in\r
215 the first name/value pair) if the request was not\r
216 successful.\r
217 @param[out] Results A null-terminated Unicode string in\r
218 <ConfigAltResp> format which has all values filled\r
219 in for the names in the Request string. String to\r
220 be allocated by the called function.\r
221\r
222 @retval EFI_SUCCESS The Results is filled with the requested values.\r
223 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
224 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
225 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
226 driver.\r
227\r
228**/\r
229EFI_STATUS\r
230EFIAPI\r
231Tcg2ExtractConfig (\r
232 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
233 IN CONST EFI_STRING Request,\r
234 OUT EFI_STRING *Progress,\r
235 OUT EFI_STRING *Results\r
236 )\r
237{\r
238 if (Progress == NULL || Results == NULL) {\r
239 return EFI_INVALID_PARAMETER;\r
240 }\r
241\r
242 *Progress = Request;\r
243 return EFI_NOT_FOUND;\r
244}\r
245\r
246/**\r
247 Save TPM request to variable space.\r
248\r
249 @param[in] PpRequest Physical Presence request command.\r
250\r
251 @retval EFI_SUCCESS The operation is finished successfully.\r
252 @retval Others Other errors as indicated.\r
253\r
254**/\r
255EFI_STATUS\r
256SaveTcg2PpRequest (\r
257 IN UINT8 PpRequest\r
258 )\r
259{\r
260 UINT32 ReturnCode;\r
261 EFI_STATUS Status;\r
262\r
263 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (PpRequest, 0);\r
264 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
265 mCurrentPpRequest = PpRequest;\r
266 Status = EFI_SUCCESS;\r
267 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {\r
268 Status = EFI_OUT_OF_RESOURCES;\r
269 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {\r
270 Status = EFI_UNSUPPORTED;\r
271 } else {\r
272 Status = EFI_DEVICE_ERROR;\r
273 }\r
274\r
275 return Status;\r
276}\r
277\r
278/**\r
279 Save TPM request to variable space.\r
280\r
281 @param[in] PpRequestParameter Physical Presence request parameter.\r
282\r
283 @retval EFI_SUCCESS The operation is finished successfully.\r
284 @retval Others Other errors as indicated.\r
285\r
286**/\r
287EFI_STATUS\r
288SaveTcg2PpRequestParameter (\r
289 IN UINT32 PpRequestParameter\r
290 )\r
291{\r
292 UINT32 ReturnCode;\r
293 EFI_STATUS Status;\r
294\r
295 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (mCurrentPpRequest, PpRequestParameter);\r
296 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
297 Status = EFI_SUCCESS;\r
298 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {\r
299 Status = EFI_OUT_OF_RESOURCES;\r
300 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {\r
301 Status = EFI_UNSUPPORTED;\r
302 } else {\r
303 Status = EFI_DEVICE_ERROR;\r
304 }\r
305\r
306 return Status;\r
307}\r
308\r
309/**\r
310 Save Tcg2 PCR Banks request request to variable space.\r
311\r
312 @param[in] PCRBankIndex PCR Bank Index.\r
313 @param[in] Enable Enable or disable this PCR Bank.\r
314\r
315 @retval EFI_SUCCESS The operation is finished successfully.\r
316 @retval Others Other errors as indicated.\r
317\r
318**/\r
319EFI_STATUS\r
320SaveTcg2PCRBanksRequest (\r
321 IN UINTN PCRBankIndex,\r
322 IN BOOLEAN Enable\r
323 )\r
324{\r
325 UINT32 ReturnCode;\r
326 EFI_STATUS Status;\r
327\r
328 if (Enable) {\r
329 mTcg2ConfigPrivateDate->PCRBanksDesired |= (0x1 << PCRBankIndex);\r
330 } else {\r
331 mTcg2ConfigPrivateDate->PCRBanksDesired &= ~(0x1 << PCRBankIndex);\r
332 }\r
333 \r
334 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, mTcg2ConfigPrivateDate->PCRBanksDesired);\r
335 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
336 Status = EFI_SUCCESS;\r
337 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {\r
338 Status = EFI_OUT_OF_RESOURCES;\r
339 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {\r
340 Status = EFI_UNSUPPORTED;\r
341 } else {\r
342 Status = EFI_DEVICE_ERROR;\r
343 }\r
344\r
345 return Status;\r
346}\r
347\r
348/**\r
349 This function processes the results of changes in configuration.\r
350\r
351 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
352 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>\r
353 format.\r
354 @param[out] Progress A pointer to a string filled in with the offset of\r
355 the most recent '&' before the first failing\r
356 name/value pair (or the beginning of the string if\r
357 the failure is in the first name/value pair) or\r
358 the terminating NULL if all was successful.\r
359\r
360 @retval EFI_SUCCESS The Results is processed successfully.\r
361 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
362 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
363 driver.\r
364\r
365**/\r
366EFI_STATUS\r
367EFIAPI\r
368Tcg2RouteConfig (\r
369 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
370 IN CONST EFI_STRING Configuration,\r
371 OUT EFI_STRING *Progress\r
372 )\r
373{\r
374 if (Configuration == NULL || Progress == NULL) {\r
375 return EFI_INVALID_PARAMETER;\r
376 }\r
377\r
378 return EFI_NOT_FOUND;\r
379}\r
380\r
a6e0e994
ZC
381/**\r
382 Get HID string of TPM2 ACPI device object\r
383\r
3304abc1 384 @param[in] Hid Points to HID String Buffer.\r
a6e0e994
ZC
385 @param[in] Size HID String size in bytes. Must >= TPM_HID_ACPI_SIZE\r
386\r
387 @return HID String get status.\r
388\r
389**/\r
390EFI_STATUS\r
391GetTpm2HID(\r
3304abc1 392 CHAR8 *Hid,\r
a6e0e994
ZC
393 UINTN Size\r
394 )\r
395{\r
396 EFI_STATUS Status;\r
397 UINT32 ManufacturerID;\r
398 UINT32 FirmwareVersion1;\r
399 UINT32 FirmwareVersion2;\r
400 BOOLEAN PnpHID;\r
401\r
402 PnpHID = TRUE;\r
403\r
3304abc1 404 ZeroMem(Hid, Size);\r
a6e0e994
ZC
405\r
406 //\r
407 // Get Manufacturer ID\r
408 //\r
409 Status = Tpm2GetCapabilityManufactureID(&ManufacturerID);\r
410 if (!EFI_ERROR(Status)) {\r
411 DEBUG((DEBUG_INFO, "TPM_PT_MANUFACTURER 0x%08x\n", ManufacturerID));\r
412 //\r
413 // ManufacturerID defined in TCG Vendor ID Registry\r
414 // may tailed with 0x00 or 0x20\r
415 //\r
416 if ((ManufacturerID >> 24) == 0x00 || ((ManufacturerID >> 24) == 0x20)) {\r
417 //\r
418 // HID containing PNP ID "NNN####"\r
419 // NNN is uppercase letter for Vendor ID specified by manufacturer\r
420 //\r
3304abc1 421 CopyMem(Hid, &ManufacturerID, 3);\r
a6e0e994
ZC
422 } else {\r
423 //\r
424 // HID containing ACP ID "NNNN####"\r
425 // NNNN is uppercase letter for Vendor ID specified by manufacturer\r
426 //\r
3304abc1 427 CopyMem(Hid, &ManufacturerID, 4);\r
a6e0e994
ZC
428 PnpHID = FALSE;\r
429 }\r
430 } else {\r
431 DEBUG ((DEBUG_ERROR, "Get TPM_PT_MANUFACTURER failed %x!\n", Status));\r
432 ASSERT(FALSE);\r
433 return Status;\r
434 }\r
435\r
436 Status = Tpm2GetCapabilityFirmwareVersion(&FirmwareVersion1, &FirmwareVersion2);\r
437 if (!EFI_ERROR(Status)) {\r
438 DEBUG((DEBUG_INFO, "TPM_PT_FIRMWARE_VERSION_1 0x%x\n", FirmwareVersion1));\r
439 DEBUG((DEBUG_INFO, "TPM_PT_FIRMWARE_VERSION_2 0x%x\n", FirmwareVersion2));\r
440 //\r
441 // #### is Firmware Version 1\r
442 //\r
443 if (PnpHID) {\r
3304abc1 444 AsciiSPrint(Hid + 3, TPM_HID_PNP_SIZE - 3, "%02d%02d", ((FirmwareVersion1 & 0xFFFF0000) >> 16), (FirmwareVersion1 && 0x0000FFFF));\r
a6e0e994 445 } else {\r
3304abc1 446 AsciiSPrint(Hid + 4, TPM_HID_ACPI_SIZE - 4, "%02d%02d", ((FirmwareVersion1 & 0xFFFF0000) >> 16), (FirmwareVersion1 && 0x0000FFFF));\r
a6e0e994
ZC
447 }\r
448\r
449 } else {\r
450 DEBUG ((DEBUG_ERROR, "Get TPM_PT_FIRMWARE_VERSION_X failed %x!\n", Status));\r
451 ASSERT(FALSE);\r
452 return Status;\r
453 }\r
454\r
455 return EFI_SUCCESS;\r
456}\r
457\r
1abfa4ce
JY
458/**\r
459 This function processes the results of changes in configuration.\r
460\r
461 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
462 @param[in] Action Specifies the type of action taken by the browser.\r
463 @param[in] QuestionId A unique value which is sent to the original\r
464 exporting driver so that it can identify the type\r
465 of data to expect.\r
466 @param[in] Type The type of value for the question.\r
467 @param[in] Value A pointer to the data being sent to the original\r
468 exporting driver.\r
469 @param[out] ActionRequest On return, points to the action requested by the\r
470 callback function.\r
471\r
472 @retval EFI_SUCCESS The callback successfully handled the action.\r
473 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
474 variable and its data.\r
475 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
476 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
477 callback.\r
478\r
479**/\r
480EFI_STATUS\r
481EFIAPI\r
482Tcg2Callback (\r
483 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
484 IN EFI_BROWSER_ACTION Action,\r
485 IN EFI_QUESTION_ID QuestionId,\r
486 IN UINT8 Type,\r
487 IN EFI_IFR_TYPE_VALUE *Value,\r
488 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
489 )\r
490{\r
a6e0e994
ZC
491 EFI_STATUS Status;\r
492 EFI_INPUT_KEY Key;\r
493 CHAR8 HidStr[16];\r
494 CHAR16 UnHidStr[16];\r
495 TCG2_CONFIG_PRIVATE_DATA *Private;\r
518b6f65 496\r
1abfa4ce
JY
497 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
498 return EFI_INVALID_PARAMETER;\r
499 }\r
518b6f65 500\r
a6e0e994
ZC
501 Private = TCG2_CONFIG_PRIVATE_DATA_FROM_THIS (This);\r
502\r
503 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
504 //\r
505 // Update TPM2 HID info\r
506 //\r
507 if (QuestionId == KEY_TPM_DEVICE) {\r
508 Status = GetTpm2HID(HidStr, 16);\r
509\r
510 if (EFI_ERROR(Status)) {\r
511 //\r
512 // Fail to get TPM2 HID\r
513 //\r
514 HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_TPM2_ACPI_HID_CONTENT), L"Unknown", NULL);\r
515 } else {\r
516 AsciiStrToUnicodeStrS(HidStr, UnHidStr, 16);\r
517 HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_TPM2_ACPI_HID_CONTENT), UnHidStr, NULL);\r
518 }\r
519 }\r
520 return EFI_SUCCESS;\r
521 }\r
522\r
518b6f65
JY
523 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
524 if (QuestionId == KEY_TPM_DEVICE_INTERFACE) {\r
518b6f65
JY
525 Status = SetPtpInterface ((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress), Value->u8);\r
526 if (EFI_ERROR (Status)) {\r
527 CreatePopUp (\r
528 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
529 &Key,\r
530 L"Error: Fail to set PTP interface!",\r
531 NULL\r
532 );\r
533 return EFI_DEVICE_ERROR;\r
534 }\r
535 }\r
536 }\r
1abfa4ce
JY
537 \r
538 if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
539 if (QuestionId == KEY_TPM_DEVICE) {\r
540 return EFI_SUCCESS;\r
541 }\r
542 if (QuestionId == KEY_TPM2_OPERATION) {\r
543 return SaveTcg2PpRequest (Value->u8);\r
544 }\r
545 if (QuestionId == KEY_TPM2_OPERATION_PARAMETER) {\r
546 return SaveTcg2PpRequestParameter (Value->u32);\r
547 }\r
548 if ((QuestionId >= KEY_TPM2_PCR_BANKS_REQUEST_0) && (QuestionId <= KEY_TPM2_PCR_BANKS_REQUEST_4)) {\r
549 SaveTcg2PCRBanksRequest (QuestionId - KEY_TPM2_PCR_BANKS_REQUEST_0, Value->b);\r
550 }\r
551 }\r
552\r
553 return EFI_UNSUPPORTED;\r
554}\r
555\r
556/**\r
557 Append Buffer With TpmAlgHash.\r
558\r
559 @param[in] Buffer Buffer to be appended.\r
560 @param[in] BufferSize Size of buffer.\r
561 @param[in] TpmAlgHash TpmAlgHash.\r
562\r
563**/\r
564VOID\r
565AppendBufferWithTpmAlgHash (\r
566 IN UINT16 *Buffer,\r
567 IN UINTN BufferSize,\r
568 IN UINT32 TpmAlgHash\r
569 )\r
570{\r
571 switch (TpmAlgHash) {\r
572 case TPM_ALG_SHA1:\r
573 if (Buffer[0] != 0) {\r
d2e8af97 574 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 575 }\r
d2e8af97 576 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1");\r
1abfa4ce
JY
577 break;\r
578 case TPM_ALG_SHA256:\r
579 if (Buffer[0] != 0) {\r
d2e8af97 580 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 581 }\r
d2e8af97 582 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256");\r
1abfa4ce
JY
583 break;\r
584 case TPM_ALG_SHA384:\r
585 if (Buffer[0] != 0) {\r
d2e8af97 586 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 587 }\r
d2e8af97 588 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384");\r
1abfa4ce
JY
589 break;\r
590 case TPM_ALG_SHA512:\r
591 if (Buffer[0] != 0) {\r
d2e8af97 592 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 593 }\r
d2e8af97 594 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA512");\r
1abfa4ce
JY
595 break;\r
596 case TPM_ALG_SM3_256:\r
597 if (Buffer[0] != 0) {\r
d2e8af97 598 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 599 }\r
d2e8af97 600 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256");\r
1abfa4ce
JY
601 break;\r
602 }\r
603}\r
604\r
605/**\r
606 Fill Buffer With BootHashAlg.\r
607\r
608 @param[in] Buffer Buffer to be filled.\r
609 @param[in] BufferSize Size of buffer.\r
610 @param[in] BootHashAlg BootHashAlg.\r
611\r
612**/\r
613VOID\r
614FillBufferWithBootHashAlg (\r
615 IN UINT16 *Buffer,\r
616 IN UINTN BufferSize,\r
617 IN UINT32 BootHashAlg\r
618 )\r
619{\r
620 Buffer[0] = 0;\r
621 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
622 if (Buffer[0] != 0) {\r
d2e8af97 623 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 624 }\r
d2e8af97 625 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1");\r
1abfa4ce
JY
626 }\r
627 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
628 if (Buffer[0] != 0) {\r
d2e8af97 629 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 630 }\r
d2e8af97 631 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256");\r
1abfa4ce
JY
632 }\r
633 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
634 if (Buffer[0] != 0) {\r
d2e8af97 635 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 636 }\r
d2e8af97 637 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384");\r
1abfa4ce
JY
638 }\r
639 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
640 if (Buffer[0] != 0) {\r
d2e8af97 641 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 642 }\r
d2e8af97 643 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA512");\r
1abfa4ce
JY
644 }\r
645 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
646 if (Buffer[0] != 0) {\r
d2e8af97 647 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 648 }\r
d2e8af97 649 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256");\r
1abfa4ce
JY
650 }\r
651}\r
652\r
c41eeb44
JY
653/**\r
654 Set ConfigInfo according to TpmAlgHash.\r
655\r
656 @param[in,out] Tcg2ConfigInfo TCG2 config info.\r
657 @param[in] TpmAlgHash TpmAlgHash.\r
658\r
659**/\r
660VOID\r
661SetConfigInfo (\r
662 IN OUT TCG2_CONFIGURATION_INFO *Tcg2ConfigInfo,\r
663 IN UINT32 TpmAlgHash\r
664 )\r
665{\r
666 switch (TpmAlgHash) {\r
667 case TPM_ALG_SHA1:\r
668 Tcg2ConfigInfo->Sha1Supported = TRUE;\r
669 break;\r
670 case TPM_ALG_SHA256:\r
671 Tcg2ConfigInfo->Sha256Supported = TRUE;\r
672 break;\r
673 case TPM_ALG_SHA384:\r
674 Tcg2ConfigInfo->Sha384Supported = TRUE;\r
675 break;\r
676 case TPM_ALG_SHA512:\r
677 Tcg2ConfigInfo->Sha512Supported = TRUE;\r
678 break;\r
679 case TPM_ALG_SM3_256:\r
680 Tcg2ConfigInfo->Sm3Supported = TRUE;\r
681 break;\r
682 }\r
683}\r
684\r
1abfa4ce
JY
685/**\r
686 Fill Buffer With TCG2EventLogFormat.\r
687\r
688 @param[in] Buffer Buffer to be filled.\r
689 @param[in] BufferSize Size of buffer.\r
690 @param[in] TCG2EventLogFormat TCG2EventLogFormat.\r
691\r
692**/\r
693VOID\r
694FillBufferWithTCG2EventLogFormat (\r
695 IN UINT16 *Buffer,\r
696 IN UINTN BufferSize,\r
697 IN UINT32 TCG2EventLogFormat\r
698 )\r
699{\r
700 Buffer[0] = 0;\r
701 if ((TCG2EventLogFormat & EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) != 0) {\r
702 if (Buffer[0] != 0) {\r
d2e8af97 703 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 704 }\r
d2e8af97 705 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"TCG_1_2");\r
1abfa4ce
JY
706 }\r
707 if ((TCG2EventLogFormat & EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) != 0) {\r
708 if (Buffer[0] != 0) {\r
d2e8af97 709 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 710 }\r
d2e8af97 711 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"TCG_2");\r
1abfa4ce
JY
712 }\r
713 if ((TCG2EventLogFormat & (~EFI_TCG2_EVENT_LOG_FORMAT_ALL)) != 0) {\r
714 if (Buffer[0] != 0) {\r
d2e8af97 715 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");\r
1abfa4ce 716 }\r
d2e8af97 717 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"UNKNOWN");\r
1abfa4ce
JY
718 }\r
719}\r
720\r
1abfa4ce
JY
721/**\r
722 This function publish the TCG2 configuration Form for TPM device.\r
723\r
724 @param[in, out] PrivateData Points to TCG2 configuration private data.\r
725\r
726 @retval EFI_SUCCESS HII Form is installed for this network device.\r
727 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.\r
728 @retval Others Other errors as indicated.\r
729\r
730**/\r
731EFI_STATUS\r
732InstallTcg2ConfigForm (\r
733 IN OUT TCG2_CONFIG_PRIVATE_DATA *PrivateData\r
734 )\r
735{\r
736 EFI_STATUS Status;\r
737 EFI_HII_HANDLE HiiHandle;\r
738 EFI_HANDLE DriverHandle;\r
739 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
740 UINTN Index;\r
741 TPML_PCR_SELECTION Pcrs;\r
742 CHAR16 TempBuffer[1024];\r
c41eeb44 743 TCG2_CONFIGURATION_INFO Tcg2ConfigInfo;\r
518b6f65 744 UINT8 TpmDeviceInterfaceDetected;\r
1abfa4ce
JY
745\r
746 DriverHandle = NULL;\r
747 ConfigAccess = &PrivateData->ConfigAccess;\r
748 Status = gBS->InstallMultipleProtocolInterfaces (\r
749 &DriverHandle,\r
750 &gEfiDevicePathProtocolGuid,\r
751 &mTcg2HiiVendorDevicePath,\r
752 &gEfiHiiConfigAccessProtocolGuid,\r
753 ConfigAccess,\r
754 NULL\r
755 );\r
756 if (EFI_ERROR (Status)) {\r
757 return Status;\r
758 }\r
759\r
760 PrivateData->DriverHandle = DriverHandle;\r
761\r
762 //\r
763 // Publish the HII package list\r
764 //\r
765 HiiHandle = HiiAddPackages (\r
766 &gTcg2ConfigFormSetGuid,\r
767 DriverHandle,\r
768 Tcg2ConfigDxeStrings,\r
769 Tcg2ConfigBin,\r
770 NULL\r
771 );\r
772 if (HiiHandle == NULL) {\r
773 gBS->UninstallMultipleProtocolInterfaces (\r
774 DriverHandle,\r
775 &gEfiDevicePathProtocolGuid,\r
776 &mTcg2HiiVendorDevicePath,\r
777 &gEfiHiiConfigAccessProtocolGuid,\r
778 ConfigAccess,\r
779 NULL\r
780 ); \r
781\r
782 return EFI_OUT_OF_RESOURCES;\r
783 }\r
784 \r
785 PrivateData->HiiHandle = HiiHandle;\r
786\r
787 //\r
788 // Update static data\r
789 //\r
790 switch (PrivateData->TpmDeviceDetected) {\r
791 case TPM_DEVICE_NULL:\r
792 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"Not Found", NULL);\r
793 break;\r
794 case TPM_DEVICE_1_2:\r
795 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"TPM 1.2", NULL);\r
796 break;\r
797 case TPM_DEVICE_2_0_DTPM:\r
518b6f65 798 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"TPM 2.0", NULL);\r
1abfa4ce
JY
799 break;\r
800 default:\r
801 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"Unknown", NULL);\r
802 break;\r
803 }\r
804\r
c41eeb44 805 ZeroMem (&Tcg2ConfigInfo, sizeof(Tcg2ConfigInfo));\r
1abfa4ce
JY
806 Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
807 if (EFI_ERROR (Status)) {\r
808 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_ACTIVE_HASH_ALGO_CONTENT), L"[Unknown]", NULL);\r
809 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_SUPPORTED_HASH_ALGO_CONTENT), L"[Unknown]", NULL);\r
810 } else {\r
811 TempBuffer[0] = 0;\r
812 for (Index = 0; Index < Pcrs.count; Index++) {\r
72388f9c 813 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
1abfa4ce
JY
814 AppendBufferWithTpmAlgHash (TempBuffer, sizeof(TempBuffer), Pcrs.pcrSelections[Index].hash);\r
815 }\r
816 }\r
817 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_ACTIVE_HASH_ALGO_CONTENT), TempBuffer, NULL);\r
818\r
819 TempBuffer[0] = 0;\r
820 for (Index = 0; Index < Pcrs.count; Index++) {\r
821 AppendBufferWithTpmAlgHash (TempBuffer, sizeof(TempBuffer), Pcrs.pcrSelections[Index].hash);\r
c41eeb44 822 SetConfigInfo (&Tcg2ConfigInfo, Pcrs.pcrSelections[Index].hash);\r
1abfa4ce
JY
823 }\r
824 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_SUPPORTED_HASH_ALGO_CONTENT), TempBuffer, NULL);\r
825 }\r
826\r
827 FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PcdGet32 (PcdTcg2HashAlgorithmBitmap));\r
828 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_BIOS_HASH_ALGO_CONTENT), TempBuffer, NULL);\r
829\r
830 //\r
831 // Tcg2 Capability\r
832 //\r
833 FillBufferWithTCG2EventLogFormat (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.SupportedEventLogs);\r
834 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_SUPPORTED_EVENT_LOG_FORMAT_CONTENT), TempBuffer, NULL);\r
835\r
836 FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.HashAlgorithmBitmap);\r
837 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_HASH_ALGO_BITMAP_CONTENT), TempBuffer, NULL);\r
838\r
839 UnicodeSPrint (TempBuffer, sizeof (TempBuffer), L"%d", PrivateData->ProtocolCapability.NumberOfPCRBanks);\r
840 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_NUMBER_OF_PCR_BANKS_CONTENT), TempBuffer, NULL);\r
841\r
842 FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.ActivePcrBanks);\r
843 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_ACTIVE_PCR_BANKS_CONTENT), TempBuffer, NULL);\r
844\r
518b6f65
JY
845 //\r
846 // Update TPM device interface type\r
847 //\r
848 if (PrivateData->TpmDeviceDetected == TPM_DEVICE_2_0_DTPM) {\r
849 TpmDeviceInterfaceDetected = GetPtpInterface ((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress));\r
850 switch (TpmDeviceInterfaceDetected) {\r
851 case TPM_DEVICE_INTERFACE_TIS:\r
852 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_STATE_CONTENT), L"TIS", NULL);\r
853 break;\r
854 case TPM_DEVICE_INTERFACE_PTP_FIFO:\r
855 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_STATE_CONTENT), L"PTP FIFO", NULL);\r
856 break;\r
857 case TPM_DEVICE_INTERFACE_PTP_CRB:\r
858 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_STATE_CONTENT), L"PTP CRB", NULL);\r
859 break;\r
860 default:\r
861 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_STATE_CONTENT), L"Unknown", NULL);\r
862 break;\r
863 }\r
864\r
865 Tcg2ConfigInfo.TpmDeviceInterfaceAttempt = TpmDeviceInterfaceDetected;\r
866 switch (TpmDeviceInterfaceDetected) {\r
867 case TPM_DEVICE_INTERFACE_TIS:\r
868 Tcg2ConfigInfo.TpmDeviceInterfacePtpFifoSupported = FALSE;\r
869 Tcg2ConfigInfo.TpmDeviceInterfacePtpCrbSupported = FALSE;\r
870 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_CAPABILITY_CONTENT), L"TIS", NULL);\r
871 break;\r
872 case TPM_DEVICE_INTERFACE_PTP_FIFO:\r
873 case TPM_DEVICE_INTERFACE_PTP_CRB:\r
874 Tcg2ConfigInfo.TpmDeviceInterfacePtpFifoSupported = IsPtpFifoSupported((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress));\r
875 Tcg2ConfigInfo.TpmDeviceInterfacePtpCrbSupported = IsPtpCrbSupported((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress));\r
876 TempBuffer[0] = 0;\r
877 if (Tcg2ConfigInfo.TpmDeviceInterfacePtpFifoSupported) {\r
878 if (TempBuffer[0] != 0) {\r
879 StrCatS (TempBuffer, sizeof(TempBuffer) / sizeof (CHAR16), L", ");\r
880 }\r
881 StrCatS (TempBuffer, sizeof(TempBuffer) / sizeof (CHAR16), L"PTP FIFO");\r
882 }\r
883 if (Tcg2ConfigInfo.TpmDeviceInterfacePtpCrbSupported) {\r
884 if (TempBuffer[0] != 0) {\r
885 StrCatS (TempBuffer, sizeof(TempBuffer) / sizeof (CHAR16), L", ");\r
886 }\r
887 StrCatS (TempBuffer, sizeof(TempBuffer) / sizeof (CHAR16), L"PTP CRB");\r
888 }\r
889 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_CAPABILITY_CONTENT), TempBuffer, NULL);\r
890 break;\r
891 default:\r
892 Tcg2ConfigInfo.TpmDeviceInterfacePtpFifoSupported = FALSE;\r
893 Tcg2ConfigInfo.TpmDeviceInterfacePtpCrbSupported = FALSE;\r
894 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_CAPABILITY_CONTENT), L"Unknown", NULL);\r
895 break;\r
896 }\r
897 }\r
898\r
c41eeb44
JY
899 //\r
900 // Set ConfigInfo, to control the check box.\r
901 //\r
902 Status = gRT->SetVariable (\r
903 TCG2_STORAGE_INFO_NAME,\r
904 &gTcg2ConfigFormSetGuid,\r
905 EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
906 sizeof(Tcg2ConfigInfo),\r
907 &Tcg2ConfigInfo\r
908 );\r
909 if (EFI_ERROR (Status)) {\r
910 DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_STORAGE_INFO_NAME\n"));\r
911 }\r
1abfa4ce
JY
912 return EFI_SUCCESS; \r
913}\r
914\r
915/**\r
916 This function removes TCG2 configuration Form.\r
917\r
918 @param[in, out] PrivateData Points to TCG2 configuration private data.\r
919\r
920**/\r
921VOID\r
922UninstallTcg2ConfigForm (\r
923 IN OUT TCG2_CONFIG_PRIVATE_DATA *PrivateData\r
924 )\r
925{\r
926 //\r
927 // Uninstall HII package list\r
928 //\r
929 if (PrivateData->HiiHandle != NULL) {\r
930 HiiRemovePackages (PrivateData->HiiHandle);\r
931 PrivateData->HiiHandle = NULL;\r
932 }\r
933\r
934 //\r
935 // Uninstall HII Config Access Protocol\r
936 //\r
937 if (PrivateData->DriverHandle != NULL) {\r
938 gBS->UninstallMultipleProtocolInterfaces (\r
939 PrivateData->DriverHandle,\r
940 &gEfiDevicePathProtocolGuid,\r
941 &mTcg2HiiVendorDevicePath,\r
942 &gEfiHiiConfigAccessProtocolGuid,\r
943 &PrivateData->ConfigAccess,\r
944 NULL\r
945 );\r
946 PrivateData->DriverHandle = NULL;\r
947 }\r
948 \r
949 FreePool (PrivateData);\r
950}\r