From 0be9d32bc3af5b3062bb2554efc174158ca449e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20D=C3=ADaz=20Fau?= Date: Sat, 13 Jun 2020 17:24:22 +0200 Subject: [PATCH] Fixed Unicode strings issue with Windows API calls Added more NIL checks in TChromiumCore --- source/uCEFApplicationCore.pas | 33 ++--- source/uCEFChromiumCore.pas | 222 ++++++++++++++++++--------------- source/uCEFMiscFunctions.pas | 67 +++++----- update_CEF4Delphi.json | 2 +- 4 files changed, 183 insertions(+), 141 deletions(-) diff --git a/source/uCEFApplicationCore.pas b/source/uCEFApplicationCore.pas index d6dbb87c..d6d23c17 100644 --- a/source/uCEFApplicationCore.pas +++ b/source/uCEFApplicationCore.pas @@ -235,10 +235,10 @@ type procedure SetLocalesDirPath(const aValue : ustring); procedure SetOsmodalLoop(aValue : boolean); - function GetChromeVersion : string; - function GetLibCefVersion : string; - function GetLibCefPath : string; - function GetChromeElfPath : string; + function GetChromeVersion : ustring; + function GetLibCefVersion : ustring; + function GetLibCefPath : ustring; + function GetChromeElfPath : ustring; function GetMustCreateResourceBundleHandler : boolean; virtual; function GetMustCreateBrowserProcessHandler : boolean; virtual; function GetMustCreateRenderProcessHandler : boolean; virtual; @@ -457,10 +457,10 @@ type property ChromeMinorVer : uint16 read FChromeVersionInfo.MinorVer; property ChromeRelease : uint16 read FChromeVersionInfo.Release; property ChromeBuild : uint16 read FChromeVersionInfo.Build; - property ChromeVersion : string read GetChromeVersion; - property LibCefVersion : string read GetLibCefVersion; - property LibCefPath : string read GetLibCefPath; - property ChromeElfPath : string read GetChromeElfPath; + property ChromeVersion : ustring read GetChromeVersion; + property LibCefVersion : ustring read GetLibCefVersion; + property LibCefPath : ustring read GetLibCefPath; + property ChromeElfPath : ustring read GetChromeElfPath; property LibLoaded : boolean read FLibLoaded; property LogProcessInfo : boolean read FLogProcessInfo write FLogProcessInfo; property ReRaiseExceptions : boolean read FReRaiseExceptions write FReRaiseExceptions; @@ -833,12 +833,12 @@ begin // Is implemented by TCefApplication end; -function TCefApplicationCore.GetChromeVersion : string; +function TCefApplicationCore.GetChromeVersion : ustring; begin Result := FileVersionInfoToString(FChromeVersionInfo); end; -function TCefApplicationCore.GetLibCefVersion : string; +function TCefApplicationCore.GetLibCefVersion : ustring; begin Result := IntToStr(CEF_SUPPORTED_VERSION_MAJOR) + '.' + IntToStr(CEF_SUPPORTED_VERSION_MINOR) + '.' + @@ -846,7 +846,7 @@ begin IntToStr(CEF_SUPPORTED_VERSION_BUILD); end; -function TCefApplicationCore.GetLibCefPath : string; +function TCefApplicationCore.GetLibCefPath : ustring; begin if (length(FFrameworkDirPath) > 0) then Result := IncludeTrailingPathDelimiter(FFrameworkDirPath) + LIBCEF_DLL @@ -854,7 +854,7 @@ begin Result := LIBCEF_DLL; end; -function TCefApplicationCore.GetChromeElfPath : string; +function TCefApplicationCore.GetChromeElfPath : ustring; begin if (length(FFrameworkDirPath) > 0) then Result := IncludeTrailingPathDelimiter(FFrameworkDirPath) + CHROMEELF_DLL @@ -2006,6 +2006,9 @@ end; function TCefApplicationCore.LoadCEFlibrary : boolean; var TempOldDir, TempString : string; + {$IFDEF MSWINDOWS} + TempError : DWORD; + {$ENDIF} begin Result := False; @@ -2025,7 +2028,7 @@ begin end; {$IFDEF MSWINDOWS} - FLibHandle := LoadLibraryEx(PChar(LibCefPath), 0, LOAD_WITH_ALTERED_SEARCH_PATH); + FLibHandle := LoadLibraryExW(PWideChar(LibCefPath), 0, LOAD_WITH_ALTERED_SEARCH_PATH); {$ELSE} FLibHandle := LoadLibrary(PChar(LibCefPath)); {$ENDIF} @@ -2035,8 +2038,10 @@ begin FStatus := asErrorLoadingLibrary; {$IFDEF MSWINDOWS} + TempError := GetLastError; TempString := 'Error loading libcef.dll' + CRLF + CRLF + - 'Error code : 0x' + inttohex(GetLastError, 8); + 'Error code : 0x' + inttohex(TempError, 8) + CRLF + + SysErrorMessage(TempError); {$ELSE} TempString := 'Error loading the CEF binaries'; {$ENDIF} diff --git a/source/uCEFChromiumCore.pas b/source/uCEFChromiumCore.pas index b4d4b538..44a0dc0d 100644 --- a/source/uCEFChromiumCore.pas +++ b/source/uCEFChromiumCore.pas @@ -1175,9 +1175,13 @@ end; procedure TChromiumCore.DestroyAllBrowsers; begin - FBrowsersCS.Acquire; - if (FBrowsers <> nil) then FreeAndNil(FBrowsers); - FBrowsersCS.Release; + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; + if (FBrowsers <> nil) then FreeAndNil(FBrowsers); + finally + FBrowsersCS.Release; + end; end; procedure TChromiumCore.BeforeDestruction; @@ -1619,7 +1623,7 @@ begin if not(csDesigning in ComponentState) and (BrowserId = 0) and (GlobalCEFApp <> nil) and - GlobalCEFApp.GlobalContextInitialized and + GlobalCEFApp.GlobalContextInitialized and CreateClientHandler(not(ValidCefWindowHandle(aParentHandle))) then begin GetSettings(FBrowserSettings); @@ -1879,12 +1883,13 @@ end; procedure TChromiumCore.CloseAllBrowsers; begin - try - FBrowsersCS.Acquire; - if (FBrowsers <> nil) then FBrowsers.CloseAllBrowsers; - finally - FBrowsersCS.Release; - end; + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; + if (FBrowsers <> nil) then FBrowsers.CloseAllBrowsers; + finally + FBrowsersCS.Release; + end; end; function TChromiumCore.TryCloseBrowser : boolean; @@ -2381,65 +2386,75 @@ function TChromiumCore.GetBrowser : ICefBrowser; begin Result := nil; - try - FBrowsersCS.Acquire; + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; - if (FBrowsers <> nil) then - begin - if FMultiBrowserMode then - Result := FBrowsers.Browser[FBrowserId] - else - Result := FBrowsers.FirstBrowser; - end; - finally - FBrowsersCS.Release; - end; + if (FBrowsers <> nil) then + begin + if FMultiBrowserMode then + Result := FBrowsers.Browser[FBrowserId] + else + Result := FBrowsers.FirstBrowser; + end; + finally + FBrowsersCS.Release; + end; end; function TChromiumCore.GetBrowserId : integer; begin - FBrowsersCS.Acquire; - Result := FBrowserId; - FBrowsersCS.Release; + Result := 0; + + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; + Result := FBrowserId; + finally + FBrowsersCS.Release; + end; end; function TChromiumCore.GetBrowserById(aID : integer) : ICefBrowser; begin Result := nil; - try - FBrowsersCS.Acquire; - if (FBrowsers <> nil) then - Result := FBrowsers.Browser[aID]; - finally - FBrowsersCS.Release; - end; + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; + if (FBrowsers <> nil) then + Result := FBrowsers.Browser[aID]; + finally + FBrowsersCS.Release; + end; end; function TChromiumCore.GetBrowserCount : integer; begin Result := 0; - try - FBrowsersCS.Acquire; - if (FBrowsers <> nil) then - Result := FBrowsers.Count; - finally - FBrowsersCS.Release; - end; + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; + if (FBrowsers <> nil) then + Result := FBrowsers.Count; + finally + FBrowsersCS.Release; + end; end; function TChromiumCore.GetBrowserIdByIndex(aIndex : integer) : integer; begin Result := 0; - try - FBrowsersCS.Acquire; - if (FBrowsers <> nil) and (aIndex >= 0) and (aIndex < FBrowsers.Count) then - Result := TBrowserInfo(FBrowsers[aIndex]).ID; - finally - FBrowsersCS.Release; - end; + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; + if (FBrowsers <> nil) and (aIndex >= 0) and (aIndex < FBrowsers.Count) then + Result := TBrowserInfo(FBrowsers[aIndex]).ID; + finally + FBrowsersCS.Release; + end; end; function TChromiumCore.GetHasValidMainFrame : boolean; @@ -2513,9 +2528,15 @@ end; function TChromiumCore.GetInitialized : boolean; begin - FBrowsersCS.Acquire; - Result := (FBrowserId <> 0) and (FBrowsers <> nil) and not(FBrowsers.BrowserIsClosing[FBrowserId]); - FBrowsersCS.Release; + Result := False; + + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; + Result := (FBrowserId <> 0) and (FBrowsers <> nil) and not(FBrowsers.BrowserIsClosing[FBrowserId]); + finally + FBrowsersCS.Release; + end; end; function TChromiumCore.GetDocumentURL : ustring; @@ -3585,7 +3606,7 @@ begin TempLanguagesList := FAcceptLanguageList; - if (length(TempLanguagesList) = 0) then + if (length(TempLanguagesList) = 0) and (FOptions <> nil) then TempLanguagesList := FOptions.AcceptLanguageList; if (length(TempLanguagesList) = 0) then @@ -4764,81 +4785,86 @@ function TChromiumCore.RemoveBrowser(const aBrowser : ICefBrowser) : boolean; begin Result := False; - try - FBrowsersCS.Acquire; + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; - if (aBrowser <> nil) and (FBrowsers <> nil) then - begin - if FBrowsers.RemoveBrowser(aBrowser) and - (FBrowserId = aBrowser.Identifier) then - FBrowserId := FBrowsers.FirstID; - end; - finally - FBrowsersCS.Release; - end; + if (aBrowser <> nil) and (FBrowsers <> nil) then + begin + if FBrowsers.RemoveBrowser(aBrowser) and + (FBrowserId = aBrowser.Identifier) then + FBrowserId := FBrowsers.FirstID; + end; + finally + FBrowsersCS.Release; + end; end; function TChromiumCore.AddBrowser(const aBrowser : ICefBrowser) : boolean; begin Result := False; - try - FBrowsersCS.Acquire; + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; - if (aBrowser <> nil) and - (FBrowsers <> nil) and - (FMultiBrowserMode or (FBrowsers.Count = 0)) and - FBrowsers.AddBrowser(aBrowser) then - begin - Result := True; + if (aBrowser <> nil) and + (FBrowsers <> nil) and + (FMultiBrowserMode or (FBrowsers.Count = 0)) and + FBrowsers.AddBrowser(aBrowser) then + begin + Result := True; - if (FBrowserId = 0) then - FBrowserId := aBrowser.Identifier; - end; - finally - FBrowsersCS.Release; - end; + if (FBrowserId = 0) then + FBrowserId := aBrowser.Identifier; + end; + finally + FBrowsersCS.Release; + end; end; function TChromiumCore.SelectBrowser(aID : integer) : boolean; begin Result := False; - try - FBrowsersCS.Acquire; + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; - if FMultiBrowserMode and (FBrowsers <> nil) and (FBrowsers.SearchBrowser(aID) >= 0) then - begin - FBrowserId := aID; - Result := True; - end; - finally - FBrowsersCS.Release; - end; + if FMultiBrowserMode and (FBrowsers <> nil) and (FBrowsers.SearchBrowser(aID) >= 0) then + begin + FBrowserId := aID; + Result := True; + end; + finally + FBrowsersCS.Release; + end; end; function TChromiumCore.IndexOfBrowserID(aID : integer) : integer; begin Result := -1; - try - FBrowsersCS.Acquire; + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; - if (FBrowsers <> nil) then - Result := FBrowsers.SearchBrowser(aID); - finally - FBrowsersCS.Release; - end; + if (FBrowsers <> nil) then + Result := FBrowsers.SearchBrowser(aID); + finally + FBrowsersCS.Release; + end; end; procedure TChromiumCore.SetBrowserIsClosing(aID : integer); begin - try - FBrowsersCS.Acquire; - if (FBrowsers <> nil) then FBrowsers.BrowserIsClosing[aID] := True; - finally - FBrowsersCS.Release; - end; + if (FBrowsersCS <> nil) then + try + FBrowsersCS.Acquire; + if (FBrowsers <> nil) then FBrowsers.BrowserIsClosing[aID] := True; + finally + FBrowsersCS.Release; + end; end; function TChromiumCore.doOnClose(const browser: ICefBrowser): Boolean; diff --git a/source/uCEFMiscFunctions.pas b/source/uCEFMiscFunctions.pas index 78a37544..1fda6248 100644 --- a/source/uCEFMiscFunctions.pas +++ b/source/uCEFMiscFunctions.pas @@ -212,9 +212,10 @@ function CefClearCrossOriginWhitelist: Boolean; procedure UInt64ToFileVersionInfo(const aVersion : uint64; var aVersionInfo : TFileVersionInfo); {$IFDEF MSWINDOWS} -function GetExtendedFileVersion(const aFileName : string) : uint64; +function GetExtendedFileVersion(const aFileName : ustring) : uint64; function GetStringFileInfo(const aFileName, aField : string; var aValue : string) : boolean; -function GetDLLVersion(const aDLLFile : string; var aVersionInfo : TFileVersionInfo) : boolean; +function GetDLLVersion(const aDLLFile : ustring; var aVersionInfo : TFileVersionInfo) : boolean; +procedure OutputLastErrorMessage; {$ENDIF} function SplitLongString(aSrcString : string) : string; @@ -224,8 +225,8 @@ function CheckLocales(const aLocalesDirPath : string; var aMissingFiles : string function CheckResources(const aResourcesDirPath : string; var aMissingFiles : string; aCheckDevResources: boolean = True; aCheckExtensions: boolean = True) : boolean; function CheckDLLs(const aFrameworkDirPath : string; var aMissingFiles : string) : boolean; {$IFDEF MSWINDOWS} -function CheckDLLVersion(const aDLLFile : string; aMajor, aMinor, aRelease, aBuild : uint16) : boolean; -function GetDLLHeaderMachine(const aDLLFile : string; var aMachine : integer) : boolean; +function CheckDLLVersion(const aDLLFile : ustring; aMajor, aMinor, aRelease, aBuild : uint16) : boolean; +function GetDLLHeaderMachine(const aDLLFile : ustring; var aMachine : integer) : boolean; {$ENDIF} function FileVersionInfoToString(const aVersionInfo : TFileVersionInfo) : string; function CheckFilesExist(var aList : TStringList; var aMissingFiles : string) : boolean; @@ -895,7 +896,7 @@ begin {$IFDEF FMX} FMX.Types.Log.d(aMessage); {$ELSE} - {$IFNDEF FPC} + {$IFDEF MSWINDOWS} OutputDebugString({$IFDEF DELPHI12_UP}PWideChar{$ELSE}PAnsiChar{$ENDIF}(aMessage + chr(0))); {$ENDIF} {$ENDIF} @@ -1259,7 +1260,7 @@ begin end; {$IFDEF MSWINDOWS} -function GetExtendedFileVersion(const aFileName : string) : uint64; +function GetExtendedFileVersion(const aFileName : ustring) : uint64; var TempSize : DWORD; TempBuffer : pointer; @@ -1272,20 +1273,22 @@ begin try try - TempSize := GetFileVersioninfoSize(PChar(aFileName), TempHandle); + TempSize := GetFileVersionInfoSizeW(PWideChar(aFileName), TempHandle); if (TempSize > 0) then begin GetMem(TempBuffer, TempSize); - if GetFileVersionInfo(PChar(aFileName), TempHandle, TempSize, TempBuffer) and + if GetFileVersionInfoW(PWideChar(aFileName), TempHandle, TempSize, TempBuffer) and VerQueryValue(TempBuffer, '\', Pointer(TempInfo), TempLen) then begin Result := TempInfo^.dwFileVersionMS; Result := Result shl 32; Result := Result or TempInfo^.dwFileVersionLS; end; - end; + end + else + OutputLastErrorMessage; except on e : exception do if CustomExceptionHandler('GetExtendedFileVersion', e) then raise; @@ -1295,6 +1298,13 @@ begin end; end; +procedure OutputLastErrorMessage; +begin + {$IFDEF DEBUG} + OutputDebugString({$IFDEF DELPHI12_UP}PWideChar{$ELSE}PAnsiChar{$ENDIF}(SysErrorMessage(GetLastError()) + chr(0))); + {$ENDIF} +end; + function GetStringFileInfo(const aFileName, aField : string; var aValue : string) : boolean; type PLangAndCodepage = ^TLangAndCodepage; @@ -1319,13 +1329,13 @@ begin try try - TempSize := GetFileVersionInfoSize(PChar(aFileName), TempHandle); + TempSize := GetFileVersionInfoSizeW(PWideChar(aFileName), TempHandle); if (TempSize > 0) then begin GetMem(TempBuffer, TempSize); - if GetFileVersionInfo(PChar(aFileName), 0, TempSize, TempBuffer) then + if GetFileVersionInfoW(PWideChar(aFileName), 0, TempSize, TempBuffer) then begin if VerQueryValue(TempBuffer, '\VarFileInfo\Translation\', Pointer(TempLang), TempSize) then begin @@ -1352,7 +1362,7 @@ begin IntToHex(TempArray[i].wLanguage, 4) + IntToHex(TempArray[i].wCodePage, 4) + '\' + aField; - if VerQueryValue(TempBuffer, PChar(TempSubBlock), TempPointer, TempSize) then + if VerQueryValueW(TempBuffer, PWideChar(TempSubBlock), TempPointer, TempSize) then begin aValue := trim(PChar(TempPointer)); Result := (length(aValue) > 0); @@ -1368,7 +1378,7 @@ begin IntToHex(TempArray[0].wLanguage, 4) + IntToHex(1252, 4) + '\' + aField; - if VerQueryValue(TempBuffer, PChar(TempSubBlock), TempPointer, TempSize) then + if VerQueryValueW(TempBuffer, PWideChar(TempSubBlock), TempPointer, TempSize) then begin aValue := trim(PChar(TempPointer)); Result := (length(aValue) > 0); @@ -1385,7 +1395,7 @@ begin end; end; -function GetDLLVersion(const aDLLFile : string; var aVersionInfo : TFileVersionInfo) : boolean; +function GetDLLVersion(const aDLLFile : ustring; var aVersionInfo : TFileVersionInfo) : boolean; var TempVersion : uint64; begin @@ -1395,26 +1405,19 @@ begin if FileExists(aDLLFile) then begin TempVersion := GetExtendedFileVersion(aDLLFile); - UInt64ToFileVersionInfo(TempVersion, aVersionInfo); - Result := True; + if (TempVersion <> 0) then + begin + UInt64ToFileVersionInfo(TempVersion, aVersionInfo); + Result := True; + end; end; except on e : exception do if CustomExceptionHandler('GetDLLVersion', e) then raise; end; end; -{$ENDIF} -function FileVersionInfoToString(const aVersionInfo : TFileVersionInfo) : string; -begin - Result := IntToStr(aVersionInfo.MajorVer) + '.' + - IntToStr(aVersionInfo.MinorVer) + '.' + - IntToStr(aVersionInfo.Release) + '.' + - IntToStr(aVersionInfo.Build); -end; - -{$IFDEF MSWINDOWS} -function CheckDLLVersion(const aDLLFile : string; aMajor, aMinor, aRelease, aBuild : uint16) : boolean; +function CheckDLLVersion(const aDLLFile : ustring; aMajor, aMinor, aRelease, aBuild : uint16) : boolean; var TempVersionInfo : TFileVersionInfo; begin @@ -1427,7 +1430,7 @@ end; // This function is based on the answer given by 'Alex' in StackOverflow // https://stackoverflow.com/questions/2748474/how-to-determine-if-dll-file-was-compiled-as-x64-or-x86-bit-using-either-delphi -function GetDLLHeaderMachine(const aDLLFile : string; var aMachine : integer) : boolean; +function GetDLLHeaderMachine(const aDLLFile : ustring; var aMachine : integer) : boolean; var TempHeader : TImageDosHeader; TempImageNtHeaders : TImageNtHeaders; @@ -1468,6 +1471,14 @@ begin end; {$ENDIF} +function FileVersionInfoToString(const aVersionInfo : TFileVersionInfo) : string; +begin + Result := IntToStr(aVersionInfo.MajorVer) + '.' + + IntToStr(aVersionInfo.MinorVer) + '.' + + IntToStr(aVersionInfo.Release) + '.' + + IntToStr(aVersionInfo.Build); +end; + function Is32BitProcess : boolean; {$IFDEF MSWINDOWS} var diff --git a/update_CEF4Delphi.json b/update_CEF4Delphi.json index 2415845a..ac89eead 100644 --- a/update_CEF4Delphi.json +++ b/update_CEF4Delphi.json @@ -2,7 +2,7 @@ "UpdateLazPackages" : [ { "ForceNotify" : true, - "InternalVersion" : 142, + "InternalVersion" : 143, "Name" : "cef4delphi_lazarus.lpk", "Version" : "83.3.12.0" }