2 HDD password driver which is used to support HDD security feature.
4 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions
8 of the BSD License which accompanies this distribution. The
9 full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "HddPasswordDxe.h"
19 EFI_GUID mHddPasswordVendorGuid
= HDD_PASSWORD_CONFIG_GUID
;
20 CHAR16 mHddPasswordVendorStorageName
[] = L
"HDD_PASSWORD_CONFIG";
21 LIST_ENTRY mHddPasswordConfigFormList
;
22 UINT32 mNumberOfHddDevices
= 0;
24 EFI_GUID mHddPasswordDeviceInfoGuid
= HDD_PASSWORD_DEVICE_INFO_GUID
;
25 BOOLEAN mHddPasswordEndOfDxe
= FALSE
;
26 HDD_PASSWORD_REQUEST_VARIABLE
*mHddPasswordRequestVariable
= NULL
;
27 UINTN mHddPasswordRequestVariableSize
= 0;
29 HII_VENDOR_DEVICE_PATH mHddPasswordHiiVendorDevicePath
= {
35 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
36 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
39 HDD_PASSWORD_CONFIG_GUID
43 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
45 (UINT8
) (END_DEVICE_PATH_LENGTH
),
46 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
53 Check if the password is full zero.
55 @param[in] Password Points to the data buffer
57 @retval TRUE This password string is full zero.
58 @retval FALSE This password string is not full zero.
68 for (Index
= 0; Index
< HDD_PASSWORD_MAX_LENGTH
; Index
++) {
69 if (Password
[Index
] != 0) {
80 @param[in] ConfigFormEntry Points to HDD_PASSWORD_CONFIG_FORM_ENTRY buffer
81 @param[in,out] TempDevInfo Points to HDD_PASSWORD_DEVICE_INFO buffer
86 IN HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
,
87 IN OUT HDD_PASSWORD_DEVICE_INFO
*TempDevInfo
90 TempDevInfo
->Device
.Bus
= (UINT8
) ConfigFormEntry
->Bus
;
91 TempDevInfo
->Device
.Device
= (UINT8
) ConfigFormEntry
->Device
;
92 TempDevInfo
->Device
.Function
= (UINT8
) ConfigFormEntry
->Function
;
93 TempDevInfo
->Device
.Port
= ConfigFormEntry
->Port
;
94 TempDevInfo
->Device
.PortMultiplierPort
= ConfigFormEntry
->PortMultiplierPort
;
95 CopyMem (TempDevInfo
->Password
, ConfigFormEntry
->Password
, HDD_PASSWORD_MAX_LENGTH
);
96 TempDevInfo
->DevicePathLength
= (UINT32
) GetDevicePathSize (ConfigFormEntry
->DevicePath
);
97 CopyMem (TempDevInfo
->DevicePath
, ConfigFormEntry
->DevicePath
, TempDevInfo
->DevicePathLength
);
101 Build HDD password device info and save them to LockBox.
105 BuildHddPasswordDeviceInfo (
111 HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
112 HDD_PASSWORD_DEVICE_INFO
*DevInfo
;
113 HDD_PASSWORD_DEVICE_INFO
*TempDevInfo
;
116 BOOLEAN S3InitDevicesExist
;
117 UINTN S3InitDevicesLength
;
118 EFI_DEVICE_PATH_PROTOCOL
*S3InitDevices
;
119 EFI_DEVICE_PATH_PROTOCOL
*S3InitDevicesBak
;
122 // Build HDD password device info and save them to LockBox.
125 EFI_LIST_FOR_EACH (Entry
, &mHddPasswordConfigFormList
) {
126 ConfigFormEntry
= BASE_CR (Entry
, HDD_PASSWORD_CONFIG_FORM_ENTRY
, Link
);
129 // 1. Handle device which already set password.
130 // 2. When request to send freeze comamnd, driver also needs to handle device
131 // which support security feature.
133 if ((!PasswordIsFullZero (ConfigFormEntry
->Password
)) ||
134 ((ConfigFormEntry
->IfrData
.SecurityStatus
.Supported
!= 0) &&
135 (ConfigFormEntry
->IfrData
.SecurityStatus
.Enabled
== 0))) {
136 DevInfoLength
+= sizeof (HDD_PASSWORD_DEVICE_INFO
) +
137 GetDevicePathSize (ConfigFormEntry
->DevicePath
);
141 if (DevInfoLength
== 0) {
145 S3InitDevicesLength
= sizeof (DummyData
);
146 Status
= RestoreLockBox (
147 &gS3StorageDeviceInitListGuid
,
151 ASSERT ((Status
== EFI_NOT_FOUND
) || (Status
== EFI_BUFFER_TOO_SMALL
));
152 if (Status
== EFI_NOT_FOUND
) {
153 S3InitDevices
= NULL
;
154 S3InitDevicesExist
= FALSE
;
155 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
156 S3InitDevices
= AllocatePool (S3InitDevicesLength
);
157 ASSERT (S3InitDevices
!= NULL
);
159 Status
= RestoreLockBox (
160 &gS3StorageDeviceInitListGuid
,
164 ASSERT_EFI_ERROR (Status
);
165 S3InitDevicesExist
= TRUE
;
170 DevInfo
= AllocateZeroPool (DevInfoLength
);
171 ASSERT (DevInfo
!= NULL
);
173 TempDevInfo
= DevInfo
;
174 EFI_LIST_FOR_EACH (Entry
, &mHddPasswordConfigFormList
) {
175 ConfigFormEntry
= BASE_CR (Entry
, HDD_PASSWORD_CONFIG_FORM_ENTRY
, Link
);
177 if ((!PasswordIsFullZero (ConfigFormEntry
->Password
)) ||
178 ((ConfigFormEntry
->IfrData
.SecurityStatus
.Supported
!= 0) &&
179 (ConfigFormEntry
->IfrData
.SecurityStatus
.Enabled
== 0))) {
180 SaveDeviceInfo (ConfigFormEntry
, TempDevInfo
);
182 S3InitDevicesBak
= S3InitDevices
;
183 S3InitDevices
= AppendDevicePathInstance (
185 ConfigFormEntry
->DevicePath
187 if (S3InitDevicesBak
!= NULL
) {
188 FreePool (S3InitDevicesBak
);
190 ASSERT (S3InitDevices
!= NULL
);
192 TempDevInfo
= (HDD_PASSWORD_DEVICE_INFO
*) ((UINTN
)TempDevInfo
+
193 sizeof (HDD_PASSWORD_DEVICE_INFO
) +
194 TempDevInfo
->DevicePathLength
);
198 Status
= SaveLockBox (
199 &mHddPasswordDeviceInfoGuid
,
203 ASSERT_EFI_ERROR (Status
);
205 Status
= SetLockBoxAttributes (
206 &mHddPasswordDeviceInfoGuid
,
207 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
209 ASSERT_EFI_ERROR (Status
);
211 S3InitDevicesLength
= GetDevicePathSize (S3InitDevices
);
212 if (S3InitDevicesExist
) {
213 Status
= UpdateLockBox (
214 &gS3StorageDeviceInitListGuid
,
219 ASSERT_EFI_ERROR (Status
);
221 Status
= SaveLockBox (
222 &gS3StorageDeviceInitListGuid
,
226 ASSERT_EFI_ERROR (Status
);
228 Status
= SetLockBoxAttributes (
229 &gS3StorageDeviceInitListGuid
,
230 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
232 ASSERT_EFI_ERROR (Status
);
235 ZeroMem (DevInfo
, DevInfoLength
);
237 FreePool (S3InitDevices
);
241 Send freeze lock cmd through Ata Pass Thru Protocol.
243 @param[in] AtaPassThru The pointer to the ATA_PASS_THRU protocol.
244 @param[in] Port The port number of the ATA device to send the command.
245 @param[in] PortMultiplierPort The port multiplier port number of the ATA device to send the command.
246 If there is no port multiplier, then specify 0xFFFF.
248 @retval EFI_SUCCESS Successful to send freeze lock cmd.
249 @retval EFI_INVALID_PARAMETER The parameter passed-in is invalid.
250 @retval EFI_OUT_OF_RESOURCES Not enough memory to send freeze lock cmd.
251 @retval EFI_DEVICE_ERROR Can not send freeze lock cmd.
256 IN EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
,
258 IN UINT16 PortMultiplierPort
262 EFI_ATA_COMMAND_BLOCK Acb
;
263 EFI_ATA_STATUS_BLOCK
*Asb
;
264 EFI_ATA_PASS_THRU_COMMAND_PACKET Packet
;
266 if (AtaPassThru
== NULL
) {
267 return EFI_INVALID_PARAMETER
;
271 // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
272 // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
273 // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
274 // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
275 // may not be aligned when allocated on stack for some compilers. Hence, we
276 // use the API AllocateAlignedPages to ensure this structure is properly
279 Asb
= AllocateAlignedPages (
280 EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK
)),
281 AtaPassThru
->Mode
->IoAlign
284 return EFI_OUT_OF_RESOURCES
;
288 // Prepare for ATA command block.
290 ZeroMem (&Acb
, sizeof (Acb
));
291 ZeroMem (Asb
, sizeof (EFI_ATA_STATUS_BLOCK
));
292 Acb
.AtaCommand
= ATA_SECURITY_FREEZE_LOCK_CMD
;
293 Acb
.AtaDeviceHead
= (UINT8
) (PortMultiplierPort
== 0xFFFF ? 0 : (PortMultiplierPort
<< 4));
296 // Prepare for ATA pass through packet.
298 ZeroMem (&Packet
, sizeof (Packet
));
299 Packet
.Protocol
= EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA
;
300 Packet
.Length
= EFI_ATA_PASS_THRU_LENGTH_NO_DATA_TRANSFER
;
303 Packet
.Timeout
= ATA_TIMEOUT
;
305 Status
= AtaPassThru
->PassThru (
312 if (!EFI_ERROR (Status
) &&
313 ((Asb
->AtaStatus
& ATA_STSREG_ERR
) != 0) &&
314 ((Asb
->AtaError
& ATA_ERRREG_ABRT
) != 0)) {
315 Status
= EFI_DEVICE_ERROR
;
318 FreeAlignedPages (Asb
, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK
)));
320 DEBUG ((DEBUG_INFO
, "%a() - %r\n", __FUNCTION__
, Status
));
325 Get attached harddisk identify data through Ata Pass Thru Protocol.
327 @param[in] AtaPassThru The pointer to the ATA_PASS_THRU protocol.
328 @param[in] Port The port number of the ATA device to send the command.
329 @param[in] PortMultiplierPort The port multiplier port number of the ATA device to send the command.
330 If there is no port multiplier, then specify 0xFFFF.
331 @param[in] IdentifyData The buffer to store identify data.
333 @retval EFI_SUCCESS Successful to get identify data.
334 @retval EFI_INVALID_PARAMETER The parameter passed-in is invalid.
335 @retval EFI_OUT_OF_RESOURCES Not enough memory to get identify data.
336 @retval EFI_DEVICE_ERROR Can not get identify data.
340 GetHddDeviceIdentifyData (
341 IN EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
,
343 IN UINT16 PortMultiplierPort
,
344 IN ATA_IDENTIFY_DATA
*IdentifyData
348 EFI_ATA_COMMAND_BLOCK Acb
;
349 EFI_ATA_STATUS_BLOCK
*Asb
;
350 EFI_ATA_PASS_THRU_COMMAND_PACKET Packet
;
352 if ((AtaPassThru
== NULL
) || (IdentifyData
== NULL
)) {
353 return EFI_INVALID_PARAMETER
;
357 // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
358 // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
359 // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
360 // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
361 // may not be aligned when allocated on stack for some compilers. Hence, we
362 // use the API AllocateAlignedPages to ensure this structure is properly
365 Asb
= AllocateAlignedPages (
366 EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK
)),
367 AtaPassThru
->Mode
->IoAlign
370 return EFI_OUT_OF_RESOURCES
;
374 // Prepare for ATA command block.
376 ZeroMem (&Acb
, sizeof (Acb
));
377 ZeroMem (Asb
, sizeof (EFI_ATA_STATUS_BLOCK
));
378 Acb
.AtaCommand
= ATA_CMD_IDENTIFY_DRIVE
;
379 Acb
.AtaDeviceHead
= (UINT8
) (BIT7
| BIT6
| BIT5
| (PortMultiplierPort
== 0xFFFF ? 0 : (PortMultiplierPort
<< 4)));
382 // Prepare for ATA pass through packet.
384 ZeroMem (&Packet
, sizeof (Packet
));
385 Packet
.Protocol
= EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN
;
386 Packet
.Length
= EFI_ATA_PASS_THRU_LENGTH_BYTES
| EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT
;
389 Packet
.InDataBuffer
= IdentifyData
;
390 Packet
.InTransferLength
= sizeof (ATA_IDENTIFY_DATA
);
391 Packet
.Timeout
= ATA_TIMEOUT
;
393 Status
= AtaPassThru
->PassThru (
401 FreeAlignedPages (Asb
, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK
)));
407 Parse security status according to identify data.
409 @param[in] IdentifyData The buffer to store identify data.
410 @param[in, out] IfrData IFR data to hold security status.
414 GetHddPasswordSecurityStatus (
415 IN ATA_IDENTIFY_DATA
*IdentifyData
,
416 IN OUT HDD_PASSWORD_CONFIG
*IfrData
419 IfrData
->SecurityStatus
.Supported
= (IdentifyData
->command_set_supported_82
& BIT1
) ? 1 : 0;
420 IfrData
->SecurityStatus
.Enabled
= (IdentifyData
->security_status
& BIT1
) ? 1 : 0;
421 IfrData
->SecurityStatus
.Locked
= (IdentifyData
->security_status
& BIT2
) ? 1 : 0;
422 IfrData
->SecurityStatus
.Frozen
= (IdentifyData
->security_status
& BIT3
) ? 1 : 0;
423 IfrData
->SecurityStatus
.UserPasswordStatus
= IfrData
->SecurityStatus
.Enabled
;
424 IfrData
->SecurityStatus
.MasterPasswordStatus
= IfrData
->SecurityStatus
.Supported
;
426 DEBUG ((DEBUG_INFO
, "IfrData->SecurityStatus.Supported = %x\n", IfrData
->SecurityStatus
.Supported
));
427 DEBUG ((DEBUG_INFO
, "IfrData->SecurityStatus.Enabled = %x\n", IfrData
->SecurityStatus
.Enabled
));
428 DEBUG ((DEBUG_INFO
, "IfrData->SecurityStatus.Locked = %x\n", IfrData
->SecurityStatus
.Locked
));
429 DEBUG ((DEBUG_INFO
, "IfrData->SecurityStatus.Frozen = %x\n", IfrData
->SecurityStatus
.Frozen
));
430 DEBUG ((DEBUG_INFO
, "IfrData->SecurityStatus.UserPasswordStatus = %x\n", IfrData
->SecurityStatus
.UserPasswordStatus
));
431 DEBUG ((DEBUG_INFO
, "IfrData->SecurityStatus.MasterPasswordStatus = %x\n", IfrData
->SecurityStatus
.MasterPasswordStatus
));
435 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
437 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
439 @param Event Event whose notification function is being invoked.
440 @param Context Pointer to the notification function's context.
445 HddPasswordEndOfDxeEventNotify (
451 HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
453 ATA_IDENTIFY_DATA IdentifyData
;
455 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
457 mHddPasswordEndOfDxe
= TRUE
;
459 if (mHddPasswordRequestVariable
!= NULL
) {
461 // Free the HDD password request variable buffer here
462 // as the HDD password requests should have been processed.
464 FreePool (mHddPasswordRequestVariable
);
465 mHddPasswordRequestVariable
= NULL
;
466 mHddPasswordRequestVariableSize
= 0;
470 // If no any device, return directly.
472 if (IsListEmpty (&mHddPasswordConfigFormList
)) {
473 gBS
->CloseEvent (Event
);
477 BuildHddPasswordDeviceInfo ();
480 // Zero passsword and freeze lock device.
482 EFI_LIST_FOR_EACH (Entry
, &mHddPasswordConfigFormList
) {
483 ConfigFormEntry
= BASE_CR (Entry
, HDD_PASSWORD_CONFIG_FORM_ENTRY
, Link
);
485 ZeroMem (ConfigFormEntry
->Password
, HDD_PASSWORD_MAX_LENGTH
);
488 // Check whether need send freeze lock command.
489 // Below device will be froze:
490 // 1. Device not enable password.
491 // 2. Device enable password and unlocked.
493 if ((ConfigFormEntry
->IfrData
.SecurityStatus
.Supported
!= 0) &&
494 (ConfigFormEntry
->IfrData
.SecurityStatus
.Locked
== 0) &&
495 (ConfigFormEntry
->IfrData
.SecurityStatus
.Frozen
== 0)) {
496 Status
= FreezeLockDevice (ConfigFormEntry
->AtaPassThru
, ConfigFormEntry
->Port
, ConfigFormEntry
->PortMultiplierPort
);
497 DEBUG ((DEBUG_INFO
, "FreezeLockDevice return %r!\n", Status
));
498 Status
= GetHddDeviceIdentifyData (
499 ConfigFormEntry
->AtaPassThru
,
500 ConfigFormEntry
->Port
,
501 ConfigFormEntry
->PortMultiplierPort
,
504 GetHddPasswordSecurityStatus (&IdentifyData
, &ConfigFormEntry
->IfrData
);
508 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
510 gBS
->CloseEvent (Event
);
516 @param[in, out] SaltValue Points to the salt buffer, 32 bytes
521 IN OUT UINT8
*SaltValue
524 RandomSeed (NULL
, 0);
525 RandomBytes (SaltValue
, PASSWORD_SALT_SIZE
);
529 Hash the data to get credential.
531 @param[in] Buffer Points to the data buffer
532 @param[in] BufferSize Buffer size
533 @param[in] SaltValue Points to the salt buffer, 32 bytes
534 @param[out] Credential Points to the hashed result
536 @retval TRUE Hash the data successfully.
537 @retval FALSE Failed to hash the data.
545 OUT UINT8
*Credential
557 HashSize
= Sha256GetContextSize ();
558 Hash
= AllocateZeroPool (HashSize
);
559 ASSERT (Hash
!= NULL
);
564 Status
= Sha256Init (Hash
);
569 HashData
= AllocateZeroPool (PASSWORD_SALT_SIZE
+ BufferSize
);
570 ASSERT (HashData
!= NULL
);
571 if (HashData
== NULL
) {
575 CopyMem (HashData
, SaltValue
, PASSWORD_SALT_SIZE
);
576 CopyMem ((UINT8
*) HashData
+ PASSWORD_SALT_SIZE
, Buffer
, BufferSize
);
578 Status
= Sha256Update (Hash
, HashData
, PASSWORD_SALT_SIZE
+ BufferSize
);
583 Status
= Sha256Final (Hash
, Credential
);
589 if (HashData
!= NULL
) {
590 ZeroMem (HashData
, PASSWORD_SALT_SIZE
+ BufferSize
);
597 Save HDD password variable that will be used to validate HDD password
598 when the device is at frozen state.
600 @param[in] ConfigFormEntry The HDD Password configuration form entry.
601 @param[in] Password The hdd password of attached ATA device.
605 SaveHddPasswordVariable (
606 IN HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
,
611 HDD_PASSWORD_VARIABLE
*TempVariable
;
612 UINTN TempVariableSize
;
613 HDD_PASSWORD_VARIABLE
*NextNode
;
614 HDD_PASSWORD_VARIABLE
*Variable
;
616 HDD_PASSWORD_VARIABLE
*NewVariable
;
617 UINTN NewVariableSize
;
620 UINT8 HashData
[SHA256_DIGEST_SIZE
];
621 UINT8 SaltData
[PASSWORD_SALT_SIZE
];
623 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
626 if (!PasswordIsFullZero (Password
)) {
628 // It is Set/Update HDD Password.
630 ZeroMem (HashData
, sizeof (HashData
));
631 ZeroMem (SaltData
, sizeof (SaltData
));
633 HashOk
= GenerateCredential ((UINT8
*) Password
, HDD_PASSWORD_MAX_LENGTH
, SaltData
, HashData
);
635 DEBUG ((DEBUG_INFO
, "GenerateCredential failed\n"));
640 // It is Disable HDD Password.
641 // Go to delete the variable node for the HDD password device.
651 Status
= GetVariable2 (
652 HDD_PASSWORD_VARIABLE_NAME
,
653 &mHddPasswordVendorGuid
,
658 if (!EFI_ERROR (Status
) && (Variable
!= NULL
)) {
659 TempVariable
= Variable
;
660 TempVariableSize
= VariableSize
;
661 while (TempVariableSize
>= sizeof (HDD_PASSWORD_VARIABLE
)) {
662 if ((TempVariable
->Device
.Bus
== ConfigFormEntry
->Bus
) &&
663 (TempVariable
->Device
.Device
== ConfigFormEntry
->Device
) &&
664 (TempVariable
->Device
.Function
== ConfigFormEntry
->Function
) &&
665 (TempVariable
->Device
.Port
== ConfigFormEntry
->Port
) &&
666 (TempVariable
->Device
.PortMultiplierPort
== ConfigFormEntry
->PortMultiplierPort
)) {
668 // Found the node for the HDD password device.
671 NextNode
= TempVariable
+ 1;
672 CopyMem (TempVariable
, NextNode
, (UINTN
) Variable
+ VariableSize
- (UINTN
) NextNode
);
673 NewVariable
= Variable
;
674 NewVariableSize
= VariableSize
- sizeof (HDD_PASSWORD_VARIABLE
);
677 TempVariableSize
-= sizeof (HDD_PASSWORD_VARIABLE
);
680 if (NewVariable
== NULL
) {
681 DEBUG ((DEBUG_INFO
, "The variable node for the HDD password device is not found\n"));
684 DEBUG ((DEBUG_INFO
, "HddPassword variable get failed (%r)\n", Status
));
687 if (!EFI_ERROR (Status
) && (Variable
!= NULL
)) {
688 TempVariable
= Variable
;
689 TempVariableSize
= VariableSize
;
690 while (TempVariableSize
>= sizeof (HDD_PASSWORD_VARIABLE
)) {
691 if ((TempVariable
->Device
.Bus
== ConfigFormEntry
->Bus
) &&
692 (TempVariable
->Device
.Device
== ConfigFormEntry
->Device
) &&
693 (TempVariable
->Device
.Function
== ConfigFormEntry
->Function
) &&
694 (TempVariable
->Device
.Port
== ConfigFormEntry
->Port
) &&
695 (TempVariable
->Device
.PortMultiplierPort
== ConfigFormEntry
->PortMultiplierPort
)) {
697 // Found the node for the HDD password device.
700 CopyMem (TempVariable
->PasswordHash
, HashData
, sizeof (HashData
));
701 CopyMem (TempVariable
->PasswordSalt
, SaltData
, sizeof (SaltData
));
702 NewVariable
= Variable
;
703 NewVariableSize
= VariableSize
;
706 TempVariableSize
-= sizeof (HDD_PASSWORD_VARIABLE
);
709 if (NewVariable
== NULL
) {
711 // The node for the HDD password device is not found.
712 // Create node for the HDD password device.
714 NewVariableSize
= VariableSize
+ sizeof (HDD_PASSWORD_VARIABLE
);
715 NewVariable
= AllocateZeroPool (NewVariableSize
);
716 ASSERT (NewVariable
!= NULL
);
717 CopyMem (NewVariable
, Variable
, VariableSize
);
718 TempVariable
= (HDD_PASSWORD_VARIABLE
*) ((UINTN
) NewVariable
+ VariableSize
);
719 TempVariable
->Device
.Bus
= (UINT8
) ConfigFormEntry
->Bus
;
720 TempVariable
->Device
.Device
= (UINT8
) ConfigFormEntry
->Device
;
721 TempVariable
->Device
.Function
= (UINT8
) ConfigFormEntry
->Function
;
722 TempVariable
->Device
.Port
= ConfigFormEntry
->Port
;
723 TempVariable
->Device
.PortMultiplierPort
= ConfigFormEntry
->PortMultiplierPort
;
724 CopyMem (TempVariable
->PasswordHash
, HashData
, sizeof (HashData
));
725 CopyMem (TempVariable
->PasswordSalt
, SaltData
, sizeof (SaltData
));
728 NewVariableSize
= sizeof (HDD_PASSWORD_VARIABLE
);
729 NewVariable
= AllocateZeroPool (NewVariableSize
);
730 ASSERT (NewVariable
!= NULL
);
731 NewVariable
->Device
.Bus
= (UINT8
) ConfigFormEntry
->Bus
;
732 NewVariable
->Device
.Device
= (UINT8
) ConfigFormEntry
->Device
;
733 NewVariable
->Device
.Function
= (UINT8
) ConfigFormEntry
->Function
;
734 NewVariable
->Device
.Port
= ConfigFormEntry
->Port
;
735 NewVariable
->Device
.PortMultiplierPort
= ConfigFormEntry
->PortMultiplierPort
;
736 CopyMem (NewVariable
->PasswordHash
, HashData
, sizeof (HashData
));
737 CopyMem (NewVariable
->PasswordSalt
, SaltData
, sizeof (SaltData
));
741 if (NewVariable
!= NULL
) {
742 Status
= gRT
->SetVariable (
743 HDD_PASSWORD_VARIABLE_NAME
,
744 &mHddPasswordVendorGuid
,
745 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
749 if (EFI_ERROR (Status
)) {
750 DEBUG ((DEBUG_INFO
, "HddPassword variable set failed (%r)\n", Status
));
754 if (NewVariable
!= Variable
) {
755 FreePool (NewVariable
);
757 if (Variable
!= NULL
) {
761 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
765 Get saved HDD password variable that will be used to validate HDD password
766 when the device is at frozen state.
768 @param[in] ConfigFormEntry The HDD Password configuration form entry.
769 @param[out] HddPasswordVariable The variable node for the HDD password device.
771 @retval TRUE The variable node for the HDD password device is found and returned.
772 @retval FALSE The variable node for the HDD password device is not found.
776 GetSavedHddPasswordVariable (
777 IN HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
,
778 OUT HDD_PASSWORD_VARIABLE
*HddPasswordVariable
782 HDD_PASSWORD_VARIABLE
*TempVariable
;
783 HDD_PASSWORD_VARIABLE
*Variable
;
787 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
792 Status
= GetVariable2 (
793 HDD_PASSWORD_VARIABLE_NAME
,
794 &mHddPasswordVendorGuid
,
798 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
799 DEBUG ((DEBUG_INFO
, "HddPassword variable get failed (%r)\n", Status
));
804 TempVariable
= Variable
;
805 while (VariableSize
>= sizeof (HDD_PASSWORD_VARIABLE
)) {
806 if ((TempVariable
->Device
.Bus
== ConfigFormEntry
->Bus
) &&
807 (TempVariable
->Device
.Device
== ConfigFormEntry
->Device
) &&
808 (TempVariable
->Device
.Function
== ConfigFormEntry
->Function
) &&
809 (TempVariable
->Device
.Port
== ConfigFormEntry
->Port
) &&
810 (TempVariable
->Device
.PortMultiplierPort
== ConfigFormEntry
->PortMultiplierPort
)) {
812 // Found the node for the HDD password device.
815 CopyMem (HddPasswordVariable
, TempVariable
, sizeof (HDD_PASSWORD_VARIABLE
));
819 VariableSize
-= sizeof (HDD_PASSWORD_VARIABLE
);
826 DEBUG ((DEBUG_INFO
, "The variable node for the HDD password device is not found\n"));
829 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
835 Use saved HDD password variable to validate HDD password
836 when the device is at frozen state.
838 @param[in] ConfigFormEntry The HDD Password configuration form entry.
839 @param[in] Password The hdd password of attached ATA device.
841 @retval EFI_SUCCESS Pass to validate the HDD password.
842 @retval EFI_NOT_FOUND The variable node for the HDD password device is not found.
843 @retval EFI_DEVICE_ERROR Failed to generate credential for the HDD password.
844 @retval EFI_INVALID_PARAMETER Failed to validate the HDD password.
848 ValidateHddPassword (
849 IN HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
,
854 HDD_PASSWORD_VARIABLE HddPasswordVariable
;
856 UINT8 HashData
[SHA256_DIGEST_SIZE
];
858 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
860 if (!GetSavedHddPasswordVariable (ConfigFormEntry
, &HddPasswordVariable
)) {
861 DEBUG ((DEBUG_INFO
, "GetSavedHddPasswordVariable failed\n"));
862 return EFI_NOT_FOUND
;
865 ZeroMem (HashData
, sizeof (HashData
));
866 HashOk
= GenerateCredential ((UINT8
*) Password
, HDD_PASSWORD_MAX_LENGTH
, HddPasswordVariable
.PasswordSalt
, HashData
);
868 DEBUG ((DEBUG_INFO
, "GenerateCredential failed\n"));
869 return EFI_DEVICE_ERROR
;
872 if (CompareMem (HddPasswordVariable
.PasswordHash
, HashData
, sizeof (HashData
)) != 0) {
873 Status
= EFI_INVALID_PARAMETER
;
875 Status
= EFI_SUCCESS
;
878 DEBUG ((DEBUG_INFO
, "%a() - exit (%r)\n", __FUNCTION__
, Status
));
883 Send unlock hdd password cmd through Ata Pass Thru Protocol.
885 @param[in] AtaPassThru The pointer to the ATA_PASS_THRU protocol.
886 @param[in] Port The port number of the ATA device to send the command.
887 @param[in] PortMultiplierPort The port multiplier port number of the ATA device to send the command.
888 If there is no port multiplier, then specify 0xFFFF.
889 @param[in] Identifier The identifier to set user or master password.
890 @param[in] Password The hdd password of attached ATA device.
892 @retval EFI_SUCCESS Successful to send unlock hdd password cmd.
893 @retval EFI_INVALID_PARAMETER The parameter passed-in is invalid.
894 @retval EFI_OUT_OF_RESOURCES Not enough memory to send unlock hdd password cmd.
895 @retval EFI_DEVICE_ERROR Can not send unlock hdd password cmd.
900 IN EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
,
902 IN UINT16 PortMultiplierPort
,
908 EFI_ATA_COMMAND_BLOCK Acb
;
909 EFI_ATA_STATUS_BLOCK
*Asb
;
910 EFI_ATA_PASS_THRU_COMMAND_PACKET Packet
;
911 UINT8 Buffer
[HDD_PAYLOAD
];
913 if ((AtaPassThru
== NULL
) || (Password
== NULL
)) {
914 return EFI_INVALID_PARAMETER
;
918 // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
919 // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
920 // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
921 // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
922 // may not be aligned when allocated on stack for some compilers. Hence, we
923 // use the API AllocateAlignedPages to ensure this structure is properly
926 Asb
= AllocateAlignedPages (
927 EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK
)),
928 AtaPassThru
->Mode
->IoAlign
931 return EFI_OUT_OF_RESOURCES
;
935 // Prepare for ATA command block.
937 ZeroMem (&Acb
, sizeof (Acb
));
938 ZeroMem (Asb
, sizeof (EFI_ATA_STATUS_BLOCK
));
939 Acb
.AtaCommand
= ATA_SECURITY_UNLOCK_CMD
;
940 Acb
.AtaDeviceHead
= (UINT8
) (PortMultiplierPort
== 0xFFFF ? 0 : (PortMultiplierPort
<< 4));
943 // Prepare for ATA pass through packet.
945 ZeroMem (&Packet
, sizeof (Packet
));
946 Packet
.Protocol
= EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT
;
947 Packet
.Length
= EFI_ATA_PASS_THRU_LENGTH_BYTES
;
951 ((CHAR16
*) Buffer
)[0] = Identifier
& BIT0
;
952 CopyMem (&((CHAR16
*) Buffer
)[1], Password
, HDD_PASSWORD_MAX_LENGTH
);
954 Packet
.OutDataBuffer
= Buffer
;
955 Packet
.OutTransferLength
= sizeof (Buffer
);
956 Packet
.Timeout
= ATA_TIMEOUT
;
958 Status
= AtaPassThru
->PassThru (
965 if (!EFI_ERROR (Status
) &&
966 ((Asb
->AtaStatus
& ATA_STSREG_ERR
) != 0) &&
967 ((Asb
->AtaError
& ATA_ERRREG_ABRT
) != 0)) {
968 Status
= EFI_DEVICE_ERROR
;
971 FreeAlignedPages (Asb
, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK
)));
973 ZeroMem (Buffer
, sizeof (Buffer
));
975 DEBUG ((DEBUG_INFO
, "%a() - %r\n", __FUNCTION__
, Status
));
980 Send disable hdd password cmd through Ata Pass Thru Protocol.
982 @param[in] AtaPassThru The pointer to the ATA_PASS_THRU protocol.
983 @param[in] Port The port number of the ATA device to send the command.
984 @param[in] PortMultiplierPort The port multiplier port number of the ATA device to send the command.
985 If there is no port multiplier, then specify 0xFFFF.
986 @param[in] Identifier The identifier to set user or master password.
987 @param[in] Password The hdd password of attached ATA device.
989 @retval EFI_SUCCESS Successful to disable hdd password cmd.
990 @retval EFI_INVALID_PARAMETER The parameter passed-in is invalid.
991 @retval EFI_OUT_OF_RESOURCES Not enough memory to disable hdd password cmd.
992 @retval EFI_DEVICE_ERROR Can not disable hdd password cmd.
997 IN EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
,
999 IN UINT16 PortMultiplierPort
,
1000 IN CHAR8 Identifier
,
1005 EFI_ATA_COMMAND_BLOCK Acb
;
1006 EFI_ATA_STATUS_BLOCK
*Asb
;
1007 EFI_ATA_PASS_THRU_COMMAND_PACKET Packet
;
1008 UINT8 Buffer
[HDD_PAYLOAD
];
1010 if ((AtaPassThru
== NULL
) || (Password
== NULL
)) {
1011 return EFI_INVALID_PARAMETER
;
1015 // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
1016 // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
1017 // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
1018 // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
1019 // may not be aligned when allocated on stack for some compilers. Hence, we
1020 // use the API AllocateAlignedPages to ensure this structure is properly
1023 Asb
= AllocateAlignedPages (
1024 EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK
)),
1025 AtaPassThru
->Mode
->IoAlign
1028 return EFI_OUT_OF_RESOURCES
;
1032 // Prepare for ATA command block.
1034 ZeroMem (&Acb
, sizeof (Acb
));
1035 ZeroMem (Asb
, sizeof (EFI_ATA_STATUS_BLOCK
));
1036 Acb
.AtaCommand
= ATA_SECURITY_DIS_PASSWORD_CMD
;
1037 Acb
.AtaDeviceHead
= (UINT8
) (PortMultiplierPort
== 0xFFFF ? 0 : (PortMultiplierPort
<< 4));
1040 // Prepare for ATA pass through packet.
1042 ZeroMem (&Packet
, sizeof (Packet
));
1043 Packet
.Protocol
= EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT
;
1044 Packet
.Length
= EFI_ATA_PASS_THRU_LENGTH_BYTES
;
1048 ((CHAR16
*) Buffer
)[0] = Identifier
& BIT0
;
1049 CopyMem (&((CHAR16
*) Buffer
)[1], Password
, HDD_PASSWORD_MAX_LENGTH
);
1051 Packet
.OutDataBuffer
= Buffer
;
1052 Packet
.OutTransferLength
= sizeof (Buffer
);
1053 Packet
.Timeout
= ATA_TIMEOUT
;
1055 Status
= AtaPassThru
->PassThru (
1062 if (!EFI_ERROR (Status
) &&
1063 ((Asb
->AtaStatus
& ATA_STSREG_ERR
) != 0) &&
1064 ((Asb
->AtaError
& ATA_ERRREG_ABRT
) != 0)) {
1065 Status
= EFI_DEVICE_ERROR
;
1068 FreeAlignedPages (Asb
, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK
)));
1070 ZeroMem (Buffer
, sizeof (Buffer
));
1072 DEBUG ((DEBUG_INFO
, "%a() - %r\n", __FUNCTION__
, Status
));
1077 Send set hdd password cmd through Ata Pass Thru Protocol.
1079 @param[in] AtaPassThru The pointer to the ATA_PASS_THRU protocol.
1080 @param[in] Port The port number of the ATA device to send the command.
1081 @param[in] PortMultiplierPort The port multiplier port number of the ATA device to send the command.
1082 If there is no port multiplier, then specify 0xFFFF.
1083 @param[in] Identifier The identifier to set user or master password.
1084 @param[in] SecurityLevel The security level to be set to device.
1085 @param[in] MasterPasswordIdentifier The master password identifier to be set to device.
1086 @param[in] Password The hdd password of attached ATA device.
1088 @retval EFI_SUCCESS Successful to set hdd password cmd.
1089 @retval EFI_INVALID_PARAMETER The parameter passed-in is invalid.
1090 @retval EFI_OUT_OF_RESOURCES Not enough memory to set hdd password cmd.
1091 @retval EFI_DEVICE_ERROR Can not set hdd password cmd.
1096 IN EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
,
1098 IN UINT16 PortMultiplierPort
,
1099 IN CHAR8 Identifier
,
1100 IN CHAR8 SecurityLevel
,
1101 IN CHAR16 MasterPasswordIdentifier
,
1106 EFI_ATA_COMMAND_BLOCK Acb
;
1107 EFI_ATA_STATUS_BLOCK
*Asb
;
1108 EFI_ATA_PASS_THRU_COMMAND_PACKET Packet
;
1109 UINT8 Buffer
[HDD_PAYLOAD
];
1111 if ((AtaPassThru
== NULL
) || (Password
== NULL
)) {
1112 return EFI_INVALID_PARAMETER
;
1116 // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
1117 // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
1118 // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
1119 // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
1120 // may not be aligned when allocated on stack for some compilers. Hence, we
1121 // use the API AllocateAlignedPages to ensure this structure is properly
1124 Asb
= AllocateAlignedPages (
1125 EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK
)),
1126 AtaPassThru
->Mode
->IoAlign
1129 return EFI_OUT_OF_RESOURCES
;
1133 // Prepare for ATA command block.
1135 ZeroMem (&Acb
, sizeof (Acb
));
1136 ZeroMem (Asb
, sizeof (EFI_ATA_STATUS_BLOCK
));
1137 Acb
.AtaCommand
= ATA_SECURITY_SET_PASSWORD_CMD
;
1138 Acb
.AtaDeviceHead
= (UINT8
) (PortMultiplierPort
== 0xFFFF ? 0 : (PortMultiplierPort
<< 4));
1141 // Prepare for ATA pass through packet.
1143 ZeroMem (&Packet
, sizeof (Packet
));
1144 Packet
.Protocol
= EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT
;
1145 Packet
.Length
= EFI_ATA_PASS_THRU_LENGTH_BYTES
;
1149 ((CHAR16
*) Buffer
)[0] = (Identifier
| (UINT16
)(SecurityLevel
<< 8)) & (BIT0
| BIT8
);
1150 CopyMem (&((CHAR16
*) Buffer
)[1], Password
, HDD_PASSWORD_MAX_LENGTH
);
1151 if ((Identifier
& BIT0
) != 0) {
1152 ((CHAR16
*) Buffer
)[17] = MasterPasswordIdentifier
;
1155 Packet
.OutDataBuffer
= Buffer
;
1156 Packet
.OutTransferLength
= sizeof (Buffer
);
1157 Packet
.Timeout
= ATA_TIMEOUT
;
1159 Status
= AtaPassThru
->PassThru (
1166 if (!EFI_ERROR (Status
) &&
1167 ((Asb
->AtaStatus
& ATA_STSREG_ERR
) != 0) &&
1168 ((Asb
->AtaError
& ATA_ERRREG_ABRT
) != 0)) {
1169 Status
= EFI_DEVICE_ERROR
;
1172 FreeAlignedPages (Asb
, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK
)));
1174 ZeroMem (Buffer
, sizeof (Buffer
));
1176 DEBUG ((DEBUG_INFO
, "%a() - %r\n", __FUNCTION__
, Status
));
1181 Get attached harddisk model number from identify data buffer.
1183 @param[in] IdentifyData Pointer to identify data buffer.
1184 @param[in, out] String The buffer to store harddisk model number.
1188 GetHddDeviceModelNumber (
1189 IN ATA_IDENTIFY_DATA
*IdentifyData
,
1190 IN OUT CHAR16
*String
1196 // Swap the byte order in the original module name.
1197 // From Ata spec, the maximum length is 40 bytes.
1199 for (Index
= 0; Index
< 40; Index
+= 2) {
1200 String
[Index
] = IdentifyData
->ModelName
[Index
+ 1];
1201 String
[Index
+ 1] = IdentifyData
->ModelName
[Index
];
1205 // Chap it off after 20 characters
1213 Get password input from the popup windows.
1215 @param[in] PopUpString1 Pop up string 1.
1216 @param[in] PopUpString2 Pop up string 2.
1217 @param[in, out] Password The buffer to hold the input password.
1219 @retval EFI_ABORTED It is given up by pressing 'ESC' key.
1220 @retval EFI_SUCCESS Get password input successfully.
1224 PopupHddPasswordInputWindows (
1225 IN CHAR16
*PopUpString1
,
1226 IN CHAR16
*PopUpString2
,
1227 IN OUT CHAR8
*Password
1232 CHAR16 Mask
[HDD_PASSWORD_MAX_LENGTH
+ 1];
1233 CHAR16 Unicode
[HDD_PASSWORD_MAX_LENGTH
+ 1];
1234 CHAR8 Ascii
[HDD_PASSWORD_MAX_LENGTH
+ 1];
1236 ZeroMem (Unicode
, sizeof (Unicode
));
1237 ZeroMem (Ascii
, sizeof (Ascii
));
1238 ZeroMem (Mask
, sizeof (Mask
));
1240 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1244 Mask
[Length
] = L
'_';
1245 if (PopUpString2
== NULL
) {
1247 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1250 L
"---------------------",
1256 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1260 L
"---------------------",
1268 if (Key
.ScanCode
== SCAN_NULL
) {
1269 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1271 // Add the null terminator.
1273 Unicode
[Length
] = 0;
1275 } else if ((Key
.UnicodeChar
== CHAR_NULL
) ||
1276 (Key
.UnicodeChar
== CHAR_TAB
) ||
1277 (Key
.UnicodeChar
== CHAR_LINEFEED
)
1281 if (Key
.UnicodeChar
== CHAR_BACKSPACE
) {
1283 Unicode
[Length
] = 0;
1288 Unicode
[Length
] = Key
.UnicodeChar
;
1289 Mask
[Length
] = L
'*';
1291 if (Length
== HDD_PASSWORD_MAX_LENGTH
) {
1293 // Add the null terminator.
1295 Unicode
[Length
] = 0;
1303 if (Key
.ScanCode
== SCAN_ESC
) {
1304 ZeroMem (Unicode
, sizeof (Unicode
));
1305 ZeroMem (Ascii
, sizeof (Ascii
));
1306 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1311 UnicodeStrToAsciiStrS (Unicode
, Ascii
, sizeof (Ascii
));
1312 CopyMem (Password
, Ascii
, HDD_PASSWORD_MAX_LENGTH
);
1313 ZeroMem (Unicode
, sizeof (Unicode
));
1314 ZeroMem (Ascii
, sizeof (Ascii
));
1316 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1321 Check if disk is locked, show popup window and ask for password if it is.
1323 @param[in] AtaPassThru Pointer to ATA_PASSTHRU instance.
1324 @param[in] Port The port number of attached ATA device.
1325 @param[in] PortMultiplierPort The port number of port multiplier of attached ATA device.
1326 @param[in] ConfigFormEntry The HDD Password configuration form entry.
1330 HddPasswordRequestPassword (
1331 IN EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
,
1333 IN UINT16 PortMultiplierPort
,
1334 IN HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
1338 CHAR16 PopUpString
[100];
1339 ATA_IDENTIFY_DATA IdentifyData
;
1342 CHAR8 Password
[HDD_PASSWORD_MAX_LENGTH
];
1346 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1348 UnicodeSPrint (PopUpString
, sizeof (PopUpString
), L
"Unlock: %s", ConfigFormEntry
->HddString
);
1351 // Check the device security status.
1353 if ((ConfigFormEntry
->IfrData
.SecurityStatus
.Supported
) &&
1354 (ConfigFormEntry
->IfrData
.SecurityStatus
.Enabled
)) {
1356 // As soon as the HDD password is in enabled state, we pop up a window to unlock hdd
1357 // no matter it's really in locked or unlocked state.
1358 // This way forces user to enter password every time to provide best safety.
1361 Status
= PopupHddPasswordInputWindows (PopUpString
, NULL
, Password
);
1362 if (!EFI_ERROR (Status
)) {
1364 // The HDD is in locked state, unlock it by user input.
1366 if (!PasswordIsFullZero (Password
)) {
1367 if (!ConfigFormEntry
->IfrData
.SecurityStatus
.Frozen
) {
1368 Status
= UnlockHddPassword (AtaPassThru
, Port
, PortMultiplierPort
, 0, Password
);
1371 // Use saved HDD password variable to validate HDD password
1372 // when the device is at frozen state.
1374 Status
= ValidateHddPassword (ConfigFormEntry
, Password
);
1377 Status
= EFI_INVALID_PARAMETER
;
1379 if (!EFI_ERROR (Status
)) {
1380 CopyMem (ConfigFormEntry
->Password
, Password
, HDD_PASSWORD_MAX_LENGTH
);
1381 if (!ConfigFormEntry
->IfrData
.SecurityStatus
.Frozen
) {
1382 SaveHddPasswordVariable (ConfigFormEntry
, Password
);
1384 ZeroMem (Password
, HDD_PASSWORD_MAX_LENGTH
);
1385 Status
= GetHddDeviceIdentifyData (AtaPassThru
, Port
, PortMultiplierPort
, &IdentifyData
);
1386 ASSERT_EFI_ERROR (Status
);
1389 // Check the device security status again.
1391 GetHddPasswordSecurityStatus (&IdentifyData
, &ConfigFormEntry
->IfrData
);
1395 ZeroMem (Password
, HDD_PASSWORD_MAX_LENGTH
);
1397 if (EFI_ERROR (Status
)) {
1399 if (RetryCount
< MAX_HDD_PASSWORD_RETRY_COUNT
) {
1402 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1404 L
"Invalid password.",
1405 L
"Press ENTER to retry",
1408 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1413 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1415 L
"Hdd password retry count is expired. Please shutdown the machine.",
1416 L
"Press ENTER to shutdown",
1419 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1420 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1424 } else if (Status
== EFI_ABORTED
) {
1425 if (ConfigFormEntry
->IfrData
.SecurityStatus
.Locked
) {
1427 // Current device in the lock status and
1428 // User not input password and press ESC,
1429 // keep device in lock status and continue boot.
1433 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1435 L
"Press ENTER to skip the request and continue boot,",
1436 L
"Press ESC to input password again",
1439 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1441 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1442 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1444 // Keep lock and continue boot.
1449 // Let user input password again.
1455 // Current device in the unlock status and
1456 // User not input password and press ESC,
1457 // Shutdown the device.
1461 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1463 L
"Press ENTER to shutdown, Press ESC to input password again",
1466 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1468 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1469 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1472 // Let user input password again.
1483 Process Set User Pwd HDD password request.
1485 @param[in] AtaPassThru Pointer to ATA_PASSTHRU instance.
1486 @param[in] Port The port number of attached ATA device.
1487 @param[in] PortMultiplierPort The port number of port multiplier of attached ATA device.
1488 @param[in] ConfigFormEntry The HDD Password configuration form entry.
1492 ProcessHddPasswordRequestSetUserPwd (
1493 IN EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
,
1495 IN UINT16 PortMultiplierPort
,
1496 IN HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
1500 CHAR16 PopUpString
[100];
1501 ATA_IDENTIFY_DATA IdentifyData
;
1504 CHAR8 Password
[HDD_PASSWORD_MAX_LENGTH
];
1505 CHAR8 PasswordConfirm
[HDD_PASSWORD_MAX_LENGTH
];
1509 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1511 if (ConfigFormEntry
->IfrData
.SecurityStatus
.Frozen
) {
1512 DEBUG ((DEBUG_INFO
, "%s is frozen, do nothing\n", ConfigFormEntry
->HddString
));
1516 if (ConfigFormEntry
->IfrData
.SecurityStatus
.Locked
) {
1517 DEBUG ((DEBUG_INFO
, "%s is locked, do nothing\n", ConfigFormEntry
->HddString
));
1521 UnicodeSPrint (PopUpString
, sizeof (PopUpString
), L
"Set User Pwd: %s", ConfigFormEntry
->HddString
);
1524 // Check the device security status.
1526 if (ConfigFormEntry
->IfrData
.SecurityStatus
.Supported
) {
1528 Status
= PopupHddPasswordInputWindows (PopUpString
, L
"Please type in your new password", Password
);
1529 if (!EFI_ERROR (Status
)) {
1530 Status
= PopupHddPasswordInputWindows (PopUpString
, L
"Please confirm your new password", PasswordConfirm
);
1531 if (!EFI_ERROR (Status
)) {
1532 if (CompareMem (Password
, PasswordConfirm
, HDD_PASSWORD_MAX_LENGTH
) == 0) {
1533 if (!PasswordIsFullZero (Password
)) {
1534 Status
= SetHddPassword (AtaPassThru
, Port
, PortMultiplierPort
, 0, 1, 0, Password
);
1536 if (ConfigFormEntry
->IfrData
.SecurityStatus
.Enabled
) {
1537 Status
= DisableHddPassword (AtaPassThru
, Port
, PortMultiplierPort
, 0, ConfigFormEntry
->Password
);
1539 Status
= EFI_INVALID_PARAMETER
;
1542 if (!EFI_ERROR (Status
)) {
1543 CopyMem (ConfigFormEntry
->Password
, Password
, HDD_PASSWORD_MAX_LENGTH
);
1544 SaveHddPasswordVariable (ConfigFormEntry
, Password
);
1545 ZeroMem (Password
, HDD_PASSWORD_MAX_LENGTH
);
1546 ZeroMem (PasswordConfirm
, HDD_PASSWORD_MAX_LENGTH
);
1547 Status
= GetHddDeviceIdentifyData (AtaPassThru
, Port
, PortMultiplierPort
, &IdentifyData
);
1548 ASSERT_EFI_ERROR (Status
);
1551 // Check the device security status again.
1553 GetHddPasswordSecurityStatus (&IdentifyData
, &ConfigFormEntry
->IfrData
);
1558 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1560 L
"Set/Disable User Pwd failed or invalid password.",
1561 L
"Press ENTER to retry",
1564 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1569 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1571 L
"Passwords are not the same.",
1572 L
"Press ENTER to retry",
1575 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1576 Status
= EFI_INVALID_PARAMETER
;
1580 ZeroMem (Password
, HDD_PASSWORD_MAX_LENGTH
);
1581 ZeroMem (PasswordConfirm
, HDD_PASSWORD_MAX_LENGTH
);
1583 if (EFI_ERROR (Status
)) {
1585 if (RetryCount
>= MAX_HDD_PASSWORD_RETRY_COUNT
) {
1588 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1590 L
"Hdd password retry count is expired.",
1591 L
"Press ENTER to skip the request and continue boot",
1594 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1595 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1599 } else if (Status
== EFI_ABORTED
) {
1602 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1604 L
"Press ENTER to skip the request and continue boot,",
1605 L
"Press ESC to input password again",
1608 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1610 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1611 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1615 // Let user input password again.
1625 Process Set Master Pwd HDD password request.
1627 @param[in] AtaPassThru Pointer to ATA_PASSTHRU instance.
1628 @param[in] Port The port number of attached ATA device.
1629 @param[in] PortMultiplierPort The port number of port multiplier of attached ATA device.
1630 @param[in] ConfigFormEntry The HDD Password configuration form entry.
1634 ProcessHddPasswordRequestSetMasterPwd (
1635 IN EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
,
1637 IN UINT16 PortMultiplierPort
,
1638 IN HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
1642 CHAR16 PopUpString
[100];
1645 CHAR8 Password
[HDD_PASSWORD_MAX_LENGTH
];
1646 CHAR8 PasswordConfirm
[HDD_PASSWORD_MAX_LENGTH
];
1650 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1652 if (ConfigFormEntry
->IfrData
.SecurityStatus
.Frozen
) {
1653 DEBUG ((DEBUG_INFO
, "%s is frozen, do nothing\n", ConfigFormEntry
->HddString
));
1657 if (ConfigFormEntry
->IfrData
.SecurityStatus
.Locked
) {
1658 DEBUG ((DEBUG_INFO
, "%s is locked, do nothing\n", ConfigFormEntry
->HddString
));
1662 UnicodeSPrint (PopUpString
, sizeof (PopUpString
), L
"Set Master Pwd: %s", ConfigFormEntry
->HddString
);
1665 // Check the device security status.
1667 if (ConfigFormEntry
->IfrData
.SecurityStatus
.Supported
) {
1669 Status
= PopupHddPasswordInputWindows (PopUpString
, L
"Please type in your new password", Password
);
1670 if (!EFI_ERROR (Status
)) {
1671 Status
= PopupHddPasswordInputWindows (PopUpString
, L
"Please confirm your new password", PasswordConfirm
);
1672 if (!EFI_ERROR (Status
)) {
1673 if (CompareMem (Password
, PasswordConfirm
, HDD_PASSWORD_MAX_LENGTH
) == 0) {
1674 if (!PasswordIsFullZero (Password
)) {
1675 Status
= SetHddPassword (AtaPassThru
, Port
, PortMultiplierPort
, 1, 1, 1, Password
);
1677 Status
= EFI_INVALID_PARAMETER
;
1679 if (!EFI_ERROR (Status
)) {
1680 ZeroMem (Password
, HDD_PASSWORD_MAX_LENGTH
);
1681 ZeroMem (PasswordConfirm
, HDD_PASSWORD_MAX_LENGTH
);
1686 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1688 L
"Set Master Pwd failed or invalid password.",
1689 L
"Press ENTER to retry",
1692 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1697 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1699 L
"Passwords are not the same.",
1700 L
"Press ENTER to retry",
1703 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1704 Status
= EFI_INVALID_PARAMETER
;
1708 ZeroMem (Password
, HDD_PASSWORD_MAX_LENGTH
);
1709 ZeroMem (PasswordConfirm
, HDD_PASSWORD_MAX_LENGTH
);
1711 if (EFI_ERROR (Status
)) {
1713 if (RetryCount
>= MAX_HDD_PASSWORD_RETRY_COUNT
) {
1716 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1718 L
"Hdd password retry count is expired.",
1719 L
"Press ENTER to skip the request and continue boot",
1722 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1723 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1727 } else if (Status
== EFI_ABORTED
) {
1730 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1732 L
"Press ENTER to skip the request and continue boot,",
1733 L
"Press ESC to input password again",
1736 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1738 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1739 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1743 // Let user input password again.
1753 Process HDD password request.
1755 @param[in] AtaPassThru Pointer to ATA_PASSTHRU instance.
1756 @param[in] Port The port number of attached ATA device.
1757 @param[in] PortMultiplierPort The port number of port multiplier of attached ATA device.
1758 @param[in] ConfigFormEntry The HDD Password configuration form entry.
1762 ProcessHddPasswordRequest (
1763 IN EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
,
1765 IN UINT16 PortMultiplierPort
,
1766 IN HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
1770 HDD_PASSWORD_REQUEST_VARIABLE
*TempVariable
;
1771 HDD_PASSWORD_REQUEST_VARIABLE
*Variable
;
1774 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
1776 if (mHddPasswordRequestVariable
== NULL
) {
1777 Status
= GetVariable2 (
1778 HDD_PASSWORD_REQUEST_VARIABLE_NAME
,
1779 &mHddPasswordVendorGuid
,
1780 (VOID
**) &Variable
,
1783 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
1786 mHddPasswordRequestVariable
= Variable
;
1787 mHddPasswordRequestVariableSize
= VariableSize
;
1790 // Delete the HDD password request variable.
1792 Status
= gRT
->SetVariable (
1793 HDD_PASSWORD_REQUEST_VARIABLE_NAME
,
1794 &mHddPasswordVendorGuid
,
1799 ASSERT_EFI_ERROR (Status
);
1801 Variable
= mHddPasswordRequestVariable
;
1802 VariableSize
= mHddPasswordRequestVariableSize
;
1806 // Process the HDD password requests.
1808 TempVariable
= Variable
;
1809 while (VariableSize
>= sizeof (HDD_PASSWORD_REQUEST_VARIABLE
)) {
1810 if ((TempVariable
->Device
.Bus
== ConfigFormEntry
->Bus
) &&
1811 (TempVariable
->Device
.Device
== ConfigFormEntry
->Device
) &&
1812 (TempVariable
->Device
.Function
== ConfigFormEntry
->Function
) &&
1813 (TempVariable
->Device
.Port
== ConfigFormEntry
->Port
) &&
1814 (TempVariable
->Device
.PortMultiplierPort
== ConfigFormEntry
->PortMultiplierPort
)) {
1816 // Found the node for the HDD password device.
1818 if (TempVariable
->Request
.UserPassword
!= 0) {
1819 ProcessHddPasswordRequestSetUserPwd (AtaPassThru
, Port
, PortMultiplierPort
, ConfigFormEntry
);
1821 if (TempVariable
->Request
.MasterPassword
!= 0) {
1822 ProcessHddPasswordRequestSetMasterPwd (AtaPassThru
, Port
, PortMultiplierPort
, ConfigFormEntry
);
1828 VariableSize
-= sizeof (HDD_PASSWORD_REQUEST_VARIABLE
);
1832 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
1836 Get saved HDD password request.
1838 @param[in, out] ConfigFormEntry The HDD Password configuration form entry.
1842 GetSavedHddPasswordRequest (
1843 IN OUT HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
1847 HDD_PASSWORD_REQUEST_VARIABLE
*TempVariable
;
1848 HDD_PASSWORD_REQUEST_VARIABLE
*Variable
;
1851 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
1856 Status
= GetVariable2 (
1857 HDD_PASSWORD_REQUEST_VARIABLE_NAME
,
1858 &mHddPasswordVendorGuid
,
1859 (VOID
**) &Variable
,
1862 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
1866 TempVariable
= Variable
;
1867 while (VariableSize
>= sizeof (HDD_PASSWORD_REQUEST_VARIABLE
)) {
1868 if ((TempVariable
->Device
.Bus
== ConfigFormEntry
->Bus
) &&
1869 (TempVariable
->Device
.Device
== ConfigFormEntry
->Device
) &&
1870 (TempVariable
->Device
.Function
== ConfigFormEntry
->Function
) &&
1871 (TempVariable
->Device
.Port
== ConfigFormEntry
->Port
) &&
1872 (TempVariable
->Device
.PortMultiplierPort
== ConfigFormEntry
->PortMultiplierPort
)) {
1874 // Found the node for the HDD password device.
1875 // Get the HDD password request.
1877 CopyMem (&ConfigFormEntry
->IfrData
.Request
, &TempVariable
->Request
, sizeof (HDD_PASSWORD_REQUEST
));
1880 "HddPasswordRequest got: 0x%x\n",
1881 ConfigFormEntry
->IfrData
.Request
1885 VariableSize
-= sizeof (HDD_PASSWORD_REQUEST_VARIABLE
);
1889 FreePool (Variable
);
1891 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
1895 Save HDD password request.
1897 @param[in] ConfigFormEntry The HDD Password configuration form entry.
1901 SaveHddPasswordRequest (
1902 IN HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
1906 HDD_PASSWORD_REQUEST_VARIABLE
*TempVariable
;
1907 UINTN TempVariableSize
;
1908 HDD_PASSWORD_REQUEST_VARIABLE
*Variable
;
1910 HDD_PASSWORD_REQUEST_VARIABLE
*NewVariable
;
1911 UINTN NewVariableSize
;
1913 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
1917 "HddPasswordRequest to save: 0x%x\n",
1918 ConfigFormEntry
->IfrData
.Request
1924 NewVariableSize
= 0;
1926 Status
= GetVariable2 (
1927 HDD_PASSWORD_REQUEST_VARIABLE_NAME
,
1928 &mHddPasswordVendorGuid
,
1929 (VOID
**) &Variable
,
1932 if (!EFI_ERROR (Status
) && (Variable
!= NULL
)) {
1933 TempVariable
= Variable
;
1934 TempVariableSize
= VariableSize
;
1935 while (TempVariableSize
>= sizeof (HDD_PASSWORD_REQUEST_VARIABLE
)) {
1936 if ((TempVariable
->Device
.Bus
== ConfigFormEntry
->Bus
) &&
1937 (TempVariable
->Device
.Device
== ConfigFormEntry
->Device
) &&
1938 (TempVariable
->Device
.Function
== ConfigFormEntry
->Function
) &&
1939 (TempVariable
->Device
.Port
== ConfigFormEntry
->Port
) &&
1940 (TempVariable
->Device
.PortMultiplierPort
== ConfigFormEntry
->PortMultiplierPort
)) {
1942 // Found the node for the HDD password device.
1943 // Update the HDD password request.
1945 CopyMem (&TempVariable
->Request
, &ConfigFormEntry
->IfrData
.Request
, sizeof (HDD_PASSWORD_REQUEST
));
1946 NewVariable
= Variable
;
1947 NewVariableSize
= VariableSize
;
1950 TempVariableSize
-= sizeof (HDD_PASSWORD_REQUEST_VARIABLE
);
1953 if (NewVariable
== NULL
) {
1955 // The node for the HDD password device is not found.
1956 // Create node for the HDD password device.
1958 NewVariableSize
= VariableSize
+ sizeof (HDD_PASSWORD_REQUEST_VARIABLE
);
1959 NewVariable
= AllocateZeroPool (NewVariableSize
);
1960 ASSERT (NewVariable
!= NULL
);
1961 CopyMem (NewVariable
, Variable
, VariableSize
);
1962 TempVariable
= (HDD_PASSWORD_REQUEST_VARIABLE
*) ((UINTN
) NewVariable
+ VariableSize
);
1963 TempVariable
->Device
.Bus
= (UINT8
) ConfigFormEntry
->Bus
;
1964 TempVariable
->Device
.Device
= (UINT8
) ConfigFormEntry
->Device
;
1965 TempVariable
->Device
.Function
= (UINT8
) ConfigFormEntry
->Function
;
1966 TempVariable
->Device
.Port
= ConfigFormEntry
->Port
;
1967 TempVariable
->Device
.PortMultiplierPort
= ConfigFormEntry
->PortMultiplierPort
;
1968 CopyMem (&TempVariable
->Request
, &ConfigFormEntry
->IfrData
.Request
, sizeof (HDD_PASSWORD_REQUEST
));
1971 NewVariableSize
= sizeof (HDD_PASSWORD_REQUEST_VARIABLE
);
1972 NewVariable
= AllocateZeroPool (NewVariableSize
);
1973 ASSERT (NewVariable
!= NULL
);
1974 NewVariable
->Device
.Bus
= (UINT8
) ConfigFormEntry
->Bus
;
1975 NewVariable
->Device
.Device
= (UINT8
) ConfigFormEntry
->Device
;
1976 NewVariable
->Device
.Function
= (UINT8
) ConfigFormEntry
->Function
;
1977 NewVariable
->Device
.Port
= ConfigFormEntry
->Port
;
1978 NewVariable
->Device
.PortMultiplierPort
= ConfigFormEntry
->PortMultiplierPort
;
1979 CopyMem (&NewVariable
->Request
, &ConfigFormEntry
->IfrData
.Request
, sizeof (HDD_PASSWORD_REQUEST
));
1981 Status
= gRT
->SetVariable (
1982 HDD_PASSWORD_REQUEST_VARIABLE_NAME
,
1983 &mHddPasswordVendorGuid
,
1984 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1988 if (EFI_ERROR (Status
)) {
1989 DEBUG ((DEBUG_INFO
, "HddPasswordRequest variable set failed (%r)\n", Status
));
1991 if (NewVariable
!= Variable
) {
1992 FreePool (NewVariable
);
1994 if (Variable
!= NULL
) {
1995 FreePool (Variable
);
1998 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2002 Get the HDD Password configuration form entry by the index of the goto opcode actived.
2004 @param[in] Index The 0-based index of the goto opcode actived.
2006 @return The HDD Password configuration form entry found.
2008 HDD_PASSWORD_CONFIG_FORM_ENTRY
*
2009 HddPasswordGetConfigFormEntryByIndex (
2014 UINT32 CurrentIndex
;
2015 HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
2018 ConfigFormEntry
= NULL
;
2020 EFI_LIST_FOR_EACH (Entry
, &mHddPasswordConfigFormList
) {
2021 if (CurrentIndex
== Index
) {
2022 ConfigFormEntry
= BASE_CR (Entry
, HDD_PASSWORD_CONFIG_FORM_ENTRY
, Link
);
2029 return ConfigFormEntry
;
2033 This function allows the caller to request the current
2034 configuration for one or more named elements. The resulting
2035 string is in <ConfigAltResp> format. Any and all alternative
2036 configuration strings shall also be appended to the end of the
2037 current configuration string. If they are, they must appear
2038 after the current configuration. They must contain the same
2039 routing (GUID, NAME, PATH) as the current configuration string.
2040 They must have an additional description indicating the type of
2041 alternative configuration the string represents,
2042 "ALTCFG=<StringToken>". That <StringToken> (when
2043 converted from Hex UNICODE to binary) is a reference to a
2044 string in the associated string pack.
2046 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
2047 @param[in] Request A null-terminated Unicode string in
2048 <ConfigRequest> format. Note that this
2049 includes the routing information as well as
2050 the configurable name / value pairs. It is
2051 invalid for this string to be in
2052 <MultiConfigRequest> format.
2053 @param[out] Progress On return, points to a character in the
2054 Request string. Points to the string's null
2055 terminator if request was successful. Points
2056 to the most recent "&" before the first
2057 failing name / value pair (or the beginning
2058 of the string if the failure is in the first
2059 name / value pair) if the request was not
2061 @param[out] Results A null-terminated Unicode string in
2062 <ConfigAltResp> format which has all values
2063 filled in for the names in the Request string.
2064 String to be allocated by the called function.
2066 @retval EFI_SUCCESS The Results string is filled with the
2067 values corresponding to all requested
2069 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
2070 parts of the results that must be
2071 stored awaiting possible future
2073 @retval EFI_INVALID_PARAMETER For example, passing in a NULL
2074 for the Request parameter
2075 would result in this type of
2076 error. In this case, the
2077 Progress parameter would be
2079 @retval EFI_NOT_FOUND Routing data doesn't match any
2080 known driver. Progress set to the
2081 first character in the routing header.
2082 Note: There is no requirement that the
2083 driver validate the routing data. It
2084 must skip the <ConfigHdr> in order to
2086 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
2087 to most recent & before the
2088 error or the beginning of the
2090 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
2091 to the & before the name in
2092 question.Currently not implemented.
2096 HddPasswordFormExtractConfig (
2097 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
2098 IN CONST EFI_STRING Request
,
2099 OUT EFI_STRING
*Progress
,
2100 OUT EFI_STRING
*Results
2105 HDD_PASSWORD_CONFIG
*IfrData
;
2106 HDD_PASSWORD_DXE_PRIVATE_DATA
*Private
;
2107 EFI_STRING ConfigRequestHdr
;
2108 EFI_STRING ConfigRequest
;
2109 BOOLEAN AllocatedRequest
;
2112 if (Progress
== NULL
|| Results
== NULL
) {
2113 return EFI_INVALID_PARAMETER
;
2116 *Progress
= Request
;
2117 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &mHddPasswordVendorGuid
, mHddPasswordVendorStorageName
)) {
2118 return EFI_NOT_FOUND
;
2121 ConfigRequestHdr
= NULL
;
2122 ConfigRequest
= NULL
;
2123 AllocatedRequest
= FALSE
;
2126 Private
= HDD_PASSWORD_DXE_PRIVATE_FROM_THIS (This
);
2127 IfrData
= AllocateZeroPool (sizeof (HDD_PASSWORD_CONFIG
));
2128 ASSERT (IfrData
!= NULL
);
2129 if (Private
->Current
!= NULL
) {
2130 CopyMem (IfrData
, &Private
->Current
->IfrData
, sizeof (HDD_PASSWORD_CONFIG
));
2134 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
2136 BufferSize
= sizeof (HDD_PASSWORD_CONFIG
);
2137 ConfigRequest
= Request
;
2138 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
2140 // Request has no request element, construct full request string.
2141 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
2142 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
2144 ConfigRequestHdr
= HiiConstructConfigHdr (&mHddPasswordVendorGuid
, mHddPasswordVendorStorageName
, Private
->DriverHandle
);
2145 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
2146 ConfigRequest
= AllocateZeroPool (Size
);
2147 ASSERT (ConfigRequest
!= NULL
);
2148 AllocatedRequest
= TRUE
;
2149 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
2150 FreePool (ConfigRequestHdr
);
2152 Status
= gHiiConfigRouting
->BlockToConfig (
2162 // Free the allocated config request string.
2164 if (AllocatedRequest
) {
2165 FreePool (ConfigRequest
);
2166 ConfigRequest
= NULL
;
2170 // Set Progress string to the original request string.
2172 if (Request
== NULL
) {
2174 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
2175 *Progress
= Request
+ StrLen (Request
);
2182 This function applies changes in a driver's configuration.
2183 Input is a Configuration, which has the routing data for this
2184 driver followed by name / value configuration pairs. The driver
2185 must apply those pairs to its configurable storage. If the
2186 driver's configuration is stored in a linear block of data
2187 and the driver's name / value pairs are in <BlockConfig>
2188 format, it may use the ConfigToBlock helper function (above) to
2189 simplify the job. Currently not implemented.
2191 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
2192 @param[in] Configuration A null-terminated Unicode string in
2193 <ConfigString> format.
2194 @param[out] Progress A pointer to a string filled in with the
2195 offset of the most recent '&' before the
2196 first failing name / value pair (or the
2197 beginn ing of the string if the failure
2198 is in the first name / value pair) or
2199 the terminating NULL if all was
2202 @retval EFI_SUCCESS The results have been distributed or are
2203 awaiting distribution.
2204 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
2205 parts of the results that must be
2206 stored awaiting possible future
2208 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
2209 Results parameter would result
2210 in this type of error.
2211 @retval EFI_NOT_FOUND Target for the specified routing data
2216 HddPasswordFormRouteConfig (
2217 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
2218 IN CONST EFI_STRING Configuration
,
2219 OUT EFI_STRING
*Progress
2222 if (Configuration
== NULL
|| Progress
== NULL
) {
2223 return EFI_INVALID_PARAMETER
;
2227 // Check routing data in <ConfigHdr>.
2228 // Note: if only one Storage is used, then this checking could be skipped.
2230 if (!HiiIsConfigHdrMatch (Configuration
, &mHddPasswordVendorGuid
, mHddPasswordVendorStorageName
)) {
2231 *Progress
= Configuration
;
2232 return EFI_NOT_FOUND
;
2235 *Progress
= Configuration
+ StrLen (Configuration
);
2240 This function is called to provide results data to the driver.
2241 This data consists of a unique key that is used to identify
2242 which data is either being passed back or being asked for.
2244 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
2245 @param[in] Action Specifies the type of action taken by the browser.
2246 @param[in] QuestionId A unique value which is sent to the original
2247 exporting driver so that it can identify the type
2248 of data to expect. The format of the data tends to
2249 vary based on the opcode that enerated the callback.
2250 @param[in] Type The type of value for the question.
2251 @param[in] Value A pointer to the data being sent to the original
2253 @param[out] ActionRequest On return, points to the action requested by the
2256 @retval EFI_SUCCESS The callback successfully handled the action.
2257 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
2258 variable and its data.
2259 @retval EFI_DEVICE_ERROR The variable could not be saved.
2260 @retval EFI_UNSUPPORTED The specified Action is not supported by the
2261 callback.Currently not implemented.
2262 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
2263 @retval Others Other errors as indicated.
2267 HddPasswordFormCallback (
2268 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
2269 IN EFI_BROWSER_ACTION Action
,
2270 IN EFI_QUESTION_ID QuestionId
,
2272 IN EFI_IFR_TYPE_VALUE
*Value
,
2273 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
2276 HDD_PASSWORD_DXE_PRIVATE_DATA
*Private
;
2277 EFI_STRING_ID DeviceFormTitleToken
;
2278 HDD_PASSWORD_CONFIG
*IfrData
;
2279 HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
2281 if (ActionRequest
!= NULL
) {
2282 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2284 return EFI_INVALID_PARAMETER
;
2287 if ((Action
!= EFI_BROWSER_ACTION_CHANGING
) && (Action
!= EFI_BROWSER_ACTION_CHANGED
)) {
2289 // Do nothing for other UEFI Action. Only do call back when data is changing or changed.
2291 return EFI_UNSUPPORTED
;
2294 Private
= HDD_PASSWORD_DXE_PRIVATE_FROM_THIS (This
);
2297 // Retrive data from Browser
2299 IfrData
= AllocateZeroPool (sizeof (HDD_PASSWORD_CONFIG
));
2300 ASSERT (IfrData
!= NULL
);
2301 if (!HiiGetBrowserData (&mHddPasswordVendorGuid
, mHddPasswordVendorStorageName
, sizeof (HDD_PASSWORD_CONFIG
), (UINT8
*) IfrData
)) {
2303 return EFI_NOT_FOUND
;
2306 switch (QuestionId
) {
2307 case KEY_HDD_USER_PASSWORD
:
2308 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
2309 DEBUG ((DEBUG_INFO
, "KEY_HDD_USER_PASSWORD\n"));
2310 ConfigFormEntry
= Private
->Current
;
2311 ConfigFormEntry
->IfrData
.Request
.UserPassword
= Value
->b
;
2312 SaveHddPasswordRequest (ConfigFormEntry
);
2313 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
2316 case KEY_HDD_MASTER_PASSWORD
:
2317 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
2318 DEBUG ((DEBUG_INFO
, "KEY_HDD_MASTER_PASSWORD\n"));
2319 ConfigFormEntry
= Private
->Current
;
2320 ConfigFormEntry
->IfrData
.Request
.MasterPassword
= Value
->b
;
2321 SaveHddPasswordRequest (ConfigFormEntry
);
2322 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
2327 if ((QuestionId
>= KEY_HDD_DEVICE_ENTRY_BASE
) && (QuestionId
< (mNumberOfHddDevices
+ KEY_HDD_DEVICE_ENTRY_BASE
))) {
2328 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
2330 // In case goto the device configuration form, update the device form title.
2332 ConfigFormEntry
= HddPasswordGetConfigFormEntryByIndex ((UINT32
) (QuestionId
- KEY_HDD_DEVICE_ENTRY_BASE
));
2333 ASSERT (ConfigFormEntry
!= NULL
);
2335 DeviceFormTitleToken
= (EFI_STRING_ID
) STR_HDD_SECURITY_HD
;
2336 HiiSetString (Private
->HiiHandle
, DeviceFormTitleToken
, ConfigFormEntry
->HddString
, NULL
);
2338 Private
->Current
= ConfigFormEntry
;
2339 CopyMem (IfrData
, &ConfigFormEntry
->IfrData
, sizeof (HDD_PASSWORD_CONFIG
));
2347 // Pass changed uncommitted data back to Form Browser
2349 HiiSetBrowserData (&mHddPasswordVendorGuid
, mHddPasswordVendorStorageName
, sizeof (HDD_PASSWORD_CONFIG
), (UINT8
*) IfrData
, NULL
);
2356 Updates the HDD Password configuration form to add an entry for the attached
2357 ata harddisk device specified by the Controller.
2359 @param[in] HiiHandle The HII Handle associated with the registered package list.
2360 @param[in] AtaPassThru Pointer to ATA_PASSTHRU instance.
2361 @param[in] PciIo Pointer to PCI_IO instance.
2362 @param[in] Controller The controller handle of the attached ata controller.
2363 @param[in] Bus The bus number of ATA controller.
2364 @param[in] Device The device number of ATA controller.
2365 @param[in] Function The function number of ATA controller.
2366 @param[in] Port The port number of attached ATA device.
2367 @param[in] PortMultiplierPort The port number of port multiplier of attached ATA device.
2369 @retval EFI_SUCCESS The Hdd Password configuration form is updated.
2370 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
2371 @retval Others Other errors as indicated.
2375 HddPasswordConfigUpdateForm (
2376 IN EFI_HII_HANDLE HiiHandle
,
2377 IN EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
,
2378 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
2379 IN EFI_HANDLE Controller
,
2384 IN UINT16 PortMultiplierPort
2388 HDD_PASSWORD_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
2389 BOOLEAN EntryExisted
;
2391 VOID
*StartOpCodeHandle
;
2392 VOID
*EndOpCodeHandle
;
2393 EFI_IFR_GUID_LABEL
*StartLabel
;
2394 EFI_IFR_GUID_LABEL
*EndLabel
;
2395 CHAR16 HddString
[40];
2396 ATA_IDENTIFY_DATA IdentifyData
;
2397 EFI_DEVICE_PATH_PROTOCOL
*AtaDeviceNode
;
2399 ConfigFormEntry
= NULL
;
2400 EntryExisted
= FALSE
;
2402 EFI_LIST_FOR_EACH (Entry
, &mHddPasswordConfigFormList
) {
2403 ConfigFormEntry
= BASE_CR (Entry
, HDD_PASSWORD_CONFIG_FORM_ENTRY
, Link
);
2405 if ((ConfigFormEntry
->Bus
== Bus
) &&
2406 (ConfigFormEntry
->Device
== Device
) &&
2407 (ConfigFormEntry
->Function
== Function
) &&
2408 (ConfigFormEntry
->Port
== Port
) &&
2409 (ConfigFormEntry
->PortMultiplierPort
== PortMultiplierPort
)) {
2410 EntryExisted
= TRUE
;
2415 if (!EntryExisted
) {
2419 ConfigFormEntry
= AllocateZeroPool (sizeof (HDD_PASSWORD_CONFIG_FORM_ENTRY
));
2420 if (ConfigFormEntry
== NULL
) {
2421 return EFI_OUT_OF_RESOURCES
;
2424 InitializeListHead (&ConfigFormEntry
->Link
);
2425 ConfigFormEntry
->Controller
= Controller
;
2426 ConfigFormEntry
->Bus
= Bus
;
2427 ConfigFormEntry
->Device
= Device
;
2428 ConfigFormEntry
->Function
= Function
;
2429 ConfigFormEntry
->Port
= Port
;
2430 ConfigFormEntry
->PortMultiplierPort
= PortMultiplierPort
;
2431 ConfigFormEntry
->AtaPassThru
= AtaPassThru
;
2433 DEBUG ((DEBUG_INFO
, "HddPasswordDxe: Create new form for device[%d][%d] at Bus 0x%x Dev 0x%x Func 0x%x\n", Port
, PortMultiplierPort
, Bus
, Device
, Function
));
2436 // Construct the device path for the HDD password device
2438 Status
= AtaPassThru
->BuildDevicePath (
2444 if (EFI_ERROR (Status
)) {
2447 ConfigFormEntry
->DevicePath
= AppendDevicePathNode (DevicePathFromHandle (Controller
), AtaDeviceNode
);
2448 FreePool (AtaDeviceNode
);
2449 if (ConfigFormEntry
->DevicePath
== NULL
) {
2450 return EFI_OUT_OF_RESOURCES
;
2454 // Get attached harddisk model number
2456 Status
= GetHddDeviceIdentifyData (AtaPassThru
, Port
, PortMultiplierPort
, &IdentifyData
);
2457 ASSERT_EFI_ERROR (Status
);
2458 if (EFI_ERROR (Status
)) {
2461 GetHddDeviceModelNumber (&IdentifyData
, HddString
);
2463 // Compose the HDD title string and help string of this port and create a new EFI_STRING_ID.
2465 UnicodeSPrint (ConfigFormEntry
->HddString
, sizeof (ConfigFormEntry
->HddString
), L
"HDD %d:%s", mNumberOfHddDevices
, HddString
);
2466 ConfigFormEntry
->TitleToken
= HiiSetString (HiiHandle
, 0, ConfigFormEntry
->HddString
, NULL
);
2467 ConfigFormEntry
->TitleHelpToken
= HiiSetString (HiiHandle
, 0, L
"Request to set HDD Password", NULL
);
2469 GetHddPasswordSecurityStatus (&IdentifyData
, &ConfigFormEntry
->IfrData
);
2471 InsertTailList (&mHddPasswordConfigFormList
, &ConfigFormEntry
->Link
);
2474 // Init OpCode Handle
2476 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
2477 ASSERT (StartOpCodeHandle
!= NULL
);
2479 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
2480 ASSERT (EndOpCodeHandle
!= NULL
);
2483 // Create Hii Extend Label OpCode as the start opcode
2485 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
2486 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
2487 StartLabel
->Number
= HDD_DEVICE_ENTRY_LABEL
;
2490 // Create Hii Extend Label OpCode as the end opcode
2492 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
2493 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
2494 EndLabel
->Number
= HDD_DEVICE_LABEL_END
;
2496 mNumberOfHddDevices
= 0;
2497 EFI_LIST_FOR_EACH (Entry
, &mHddPasswordConfigFormList
) {
2498 ConfigFormEntry
= BASE_CR (Entry
, HDD_PASSWORD_CONFIG_FORM_ENTRY
, Link
);
2500 HiiCreateGotoOpCode (
2501 StartOpCodeHandle
, // Container for dynamic created opcodes
2502 FORMID_HDD_DEVICE_FORM
, // Target Form ID
2503 ConfigFormEntry
->TitleToken
, // Prompt text
2504 ConfigFormEntry
->TitleHelpToken
, // Help text
2505 EFI_IFR_FLAG_CALLBACK
, // Question flag
2506 (UINT16
) (KEY_HDD_DEVICE_ENTRY_BASE
+ mNumberOfHddDevices
) // Question ID
2509 mNumberOfHddDevices
++;
2514 &mHddPasswordVendorGuid
,
2515 FORMID_HDD_MAIN_FORM
,
2520 HiiFreeOpCodeHandle (StartOpCodeHandle
);
2521 HiiFreeOpCodeHandle (EndOpCodeHandle
);
2524 // Check if device is locked and prompt for password.
2526 HddPasswordRequestPassword (AtaPassThru
, Port
, PortMultiplierPort
, ConfigFormEntry
);
2529 // Process HDD password request from last boot.
2531 ProcessHddPasswordRequest (AtaPassThru
, Port
, PortMultiplierPort
, ConfigFormEntry
);
2538 Ata Pass Thru Protocol notification event handler.
2540 Check attached harddisk status to see if it's locked. If yes, then pop up a password windows to require user input.
2541 It also registers a form for user configuration on Hdd password configuration.
2543 @param[in] Event Event whose notification function is being invoked.
2544 @param[in] Context Pointer to the notification function's context.
2549 HddPasswordNotificationEvent (
2555 HDD_PASSWORD_DXE_PRIVATE_DATA
*Private
;
2556 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
2558 UINT16 PortMultiplierPort
;
2559 EFI_HANDLE Controller
;
2560 EFI_HANDLE
*HandleBuffer
;
2563 EFI_PCI_IO_PROTOCOL
*PciIo
;
2569 if (mHddPasswordEndOfDxe
) {
2570 gBS
->CloseEvent (Event
);
2574 Private
= (HDD_PASSWORD_DXE_PRIVATE_DATA
*)Context
;
2577 // Locate all handles of AtaPassThru protocol
2579 Status
= gBS
->LocateHandleBuffer (
2581 &gEfiAtaPassThruProtocolGuid
,
2586 if (EFI_ERROR (Status
)) {
2591 // Check attached hard disk status to see if it's locked
2593 for (Index
= 0; Index
< HandleCount
; Index
+= 1) {
2594 Controller
= HandleBuffer
[Index
];
2595 Status
= gBS
->HandleProtocol (
2597 &gEfiAtaPassThruProtocolGuid
,
2598 (VOID
**) &AtaPassThru
2600 if (EFI_ERROR (Status
)) {
2605 // Ignore those logical ATA_PASS_THRU instance.
2607 if ((AtaPassThru
->Mode
->Attributes
& EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL
) == 0) {
2611 Status
= gBS
->HandleProtocol (
2613 &gEfiPciIoProtocolGuid
,
2616 ASSERT_EFI_ERROR (Status
);
2617 if (EFI_ERROR (Status
)) {
2621 Status
= PciIo
->GetLocation (
2628 ASSERT_EFI_ERROR (Status
);
2629 if (EFI_ERROR (Status
)) {
2634 // Assume and only support Segment == 0.
2636 ASSERT (SegNum
== 0);
2639 // traverse all attached harddisk devices to update form and unlock it
2644 Status
= AtaPassThru
->GetNextPort (AtaPassThru
, &Port
);
2645 if (EFI_ERROR (Status
)) {
2647 // We cannot find more legal port then we are done.
2652 PortMultiplierPort
= 0xFFFF;
2654 Status
= AtaPassThru
->GetNextDevice (AtaPassThru
, Port
, &PortMultiplierPort
);
2655 if (EFI_ERROR (Status
)) {
2657 // We cannot find more legal port multiplier port number for ATA device
2658 // on the port, then we are done.
2663 // Find out the attached harddisk devices.
2664 // Try to add a HDD Password configuration page for the attached devices.
2666 gBS
->RestoreTPL (TPL_APPLICATION
);
2667 Status
= HddPasswordConfigUpdateForm (Private
->HiiHandle
, AtaPassThru
, PciIo
, Controller
, BusNum
, DevNum
, FuncNum
, Port
, PortMultiplierPort
);
2668 gBS
->RaiseTPL (TPL_CALLBACK
);
2669 if (EFI_ERROR (Status
)) {
2676 FreePool (HandleBuffer
);
2681 Initialize the HDD Password configuration form.
2683 @param[out] Instance Pointer to private instance.
2685 @retval EFI_SUCCESS The HDD Password configuration form is initialized.
2686 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
2687 @retval Others Other errors as indicated.
2690 HddPasswordConfigFormInit (
2691 OUT HDD_PASSWORD_DXE_PRIVATE_DATA
**Instance
2695 HDD_PASSWORD_DXE_PRIVATE_DATA
*Private
;
2697 InitializeListHead (&mHddPasswordConfigFormList
);
2699 Private
= AllocateZeroPool (sizeof (HDD_PASSWORD_DXE_PRIVATE_DATA
));
2700 if (Private
== NULL
) {
2701 return EFI_OUT_OF_RESOURCES
;
2704 Private
->Signature
= HDD_PASSWORD_DXE_PRIVATE_SIGNATURE
;
2706 Private
->ConfigAccess
.ExtractConfig
= HddPasswordFormExtractConfig
;
2707 Private
->ConfigAccess
.RouteConfig
= HddPasswordFormRouteConfig
;
2708 Private
->ConfigAccess
.Callback
= HddPasswordFormCallback
;
2711 // Install Device Path Protocol and Config Access protocol to driver handle
2713 Status
= gBS
->InstallMultipleProtocolInterfaces (
2714 &Private
->DriverHandle
,
2715 &gEfiDevicePathProtocolGuid
,
2716 &mHddPasswordHiiVendorDevicePath
,
2717 &gEfiHiiConfigAccessProtocolGuid
,
2718 &Private
->ConfigAccess
,
2721 ASSERT_EFI_ERROR (Status
);
2722 if (EFI_ERROR (Status
)) {
2728 // Publish our HII data
2730 Private
->HiiHandle
= HiiAddPackages (
2731 &mHddPasswordVendorGuid
,
2732 Private
->DriverHandle
,
2733 HddPasswordDxeStrings
,
2737 if (Private
->HiiHandle
== NULL
) {
2739 return EFI_OUT_OF_RESOURCES
;
2742 *Instance
= Private
;
2747 Main entry for this driver.
2749 @param ImageHandle Image handle this driver.
2750 @param SystemTable Pointer to SystemTable.
2752 @retval EFI_SUCESS This function always complete successfully.
2757 HddPasswordDxeInit (
2758 IN EFI_HANDLE ImageHandle
,
2759 IN EFI_SYSTEM_TABLE
*SystemTable
2763 HDD_PASSWORD_DXE_PRIVATE_DATA
*Private
;
2764 EFI_EVENT Registration
;
2765 EFI_EVENT EndOfDxeEvent
;
2766 EDKII_VARIABLE_LOCK_PROTOCOL
*VariableLock
;
2771 // Initialize the configuration form of HDD Password.
2773 Status
= HddPasswordConfigFormInit (&Private
);
2774 if (EFI_ERROR (Status
)) {
2779 // Register HddPasswordNotificationEvent() notify function.
2781 EfiCreateProtocolNotifyEvent (
2782 &gEfiAtaPassThruProtocolGuid
,
2784 HddPasswordNotificationEvent
,
2789 Status
= gBS
->CreateEventEx (
2792 HddPasswordEndOfDxeEventNotify
,
2794 &gEfiEndOfDxeEventGroupGuid
,
2797 ASSERT_EFI_ERROR (Status
);
2800 // Make HDD_PASSWORD_VARIABLE_NAME varible read-only.
2802 Status
= gBS
->LocateProtocol (&gEdkiiVariableLockProtocolGuid
, NULL
, (VOID
**) &VariableLock
);
2803 if (!EFI_ERROR (Status
)) {
2804 Status
= VariableLock
->RequestToLock (
2806 HDD_PASSWORD_VARIABLE_NAME
,
2807 &mHddPasswordVendorGuid
2809 DEBUG ((DEBUG_INFO
, "%a(): Lock %s variable (%r)\n", __FUNCTION__
, HDD_PASSWORD_VARIABLE_NAME
, Status
));
2810 ASSERT_EFI_ERROR (Status
);