FIX: Bug [0000705] Tries to open BitLocker ecrypted drive

This commit is contained in:
Alexander Koblov 2018-10-17 17:22:07 +00:00
commit fa370a81d3
2 changed files with 54 additions and 9 deletions

View file

@ -3,7 +3,7 @@
-------------------------------------------------------------------------
This unit contains platform depended functions.
Copyright (C) 2006-2016 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2006-2018 Alexander Koblov (alexx2000@mail.ru)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -16,8 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
along with this program. If not, see <http://www.gnu.org/licenses/>.
}
unit uOSUtils;
@ -877,28 +876,31 @@ function IsAvailable(Drive: PDrive; TryMount: Boolean): Boolean;
var
Drv: String;
DriveLabel: String;
NetResource: TNetResourceW;
wsLocalName, wsRemoteName: WideString;
begin
Drv:= ExtractFileDrive(Drive^.Path) + PathDelim;
// Try to close CD/DVD drive
if (GetDriveType(PChar(Drv)) = DRIVE_CDROM) and
if (Drive^.DriveType = dtOptical) and
TryMount and (not mbDriveReady(Drv)) then
begin
DriveLabel:= mbGetVolumeLabel(Drv, False);
mbCloseCD(Drv);
if mbDriveReady(Drv) then
mbWaitLabelChange(Drv, DriveLabel);
end;
end
// Try to connect to mapped network drive
if (Drive^.DriveType = dtNetwork) and
else if (Drive^.DriveType = dtNetwork) and
TryMount and (not mbDriveReady(Drv)) then
begin
wsLocalName := UTF8Decode(ExtractFileDrive(Drive^.Path));
wsRemoteName := UTF8Decode(Drive^.DriveLabel);
TNetworkThread.Connect(PWideChar(wsLocalName), PWideChar(wsRemoteName), RESOURCETYPE_DISK);
end;
end
// Try to unlock BitLocker Drive
else if TryMount then begin
mbDriveUnlock(Drive^.Path);
end;
Result:= mbDriveReady(Drv);
end;
{$ELSEIF DEFINED(DARWIN)}

View file

@ -3,7 +3,7 @@
-------------------------------------------------------------------------
This unit contains specific WINDOWS functions.
Copyright (C) 2006-2017 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2006-2018 Alexander Koblov (alexx2000@mail.ru)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -74,6 +74,7 @@ procedure mbWaitLabelChange(const sDrv: String; const sCurLabel: String);
@param(sDrv String specifying the root directory of a drive)
}
procedure mbCloseCD(const sDrv: String);
procedure mbDriveUnlock(const sDrv: String);
{en
Get remote file name by local file name
@param(sLocalName String specifying the local file name)
@ -355,6 +356,48 @@ begin
mciSendCommandA(OpenParms.wDeviceID, MCI_CLOSE, MCI_OPEN_TYPE or MCI_OPEN_ELEMENT, DWORD_PTR(@OpenParms));
end;
procedure mbDriveUnlock(const sDrv: String);
const
FVE_E_LOCKED_VOLUME = HRESULT($80310000);
FVE_E_VOLUME_NOT_BOUND = HRESULT($80310017);
var
Msg: TMSG;
LastError: HRESULT;
wsDrive: UnicodeString;
lpExecInfo: TShellExecuteInfoW;
begin
wsDrive:= UTF8Decode(sDrv);
if not GetDiskFreeSpaceExW(PWideChar(wsDrive), nil, nil, nil) then
begin
LastError:= GetLastError;
if (LastError = FVE_E_LOCKED_VOLUME) or (LastError = FVE_E_VOLUME_NOT_BOUND) then
begin
ZeroMemory(@lpExecInfo, SizeOf(lpExecInfo));
lpExecInfo.cbSize:= SizeOf(lpExecInfo);
lpExecInfo.fMask:= SEE_MASK_NOCLOSEPROCESS;
lpExecInfo.lpFile:= PWideChar(wsDrive);
lpExecInfo.lpVerb:= 'unlock-bde';
if ShellExecuteExW(@lpExecInfo) and (lpExecInfo.hProcess <> 0) then
begin
while (WaitForSingleObject(lpExecInfo.hProcess, 100) = WAIT_TIMEOUT) do
begin
if (GetAsyncKeyStateEx(VK_ESCAPE)) then
begin
TerminateProcess(lpExecInfo.hProcess, 1);
Break;
end;
PeekMessageW({%H-}Msg, 0, 0, 0, PM_REMOVE);
end;
{
if GetExitCodeProcess(lpExecInfo.hProcess, @LastError) then
Result:= (LastError = 0);
}
CloseHandle(lpExecInfo.hProcess);
end;
end;
end;
end;
function mbGetRemoteFileName(const sLocalName: String): String;
var
dwResult,