WebView2 - IMA trying to change an option (ICoreWebView2xyz)

Just starting out? Need help? Post your questions and find answers here.
User avatar
Derren
Enthusiast
Enthusiast
Posts: 319
Joined: Sat Jul 23, 2011 1:13 am
Location: Germany

WebView2 - IMA trying to change an option (ICoreWebView2xyz)

Post by Derren »

Hi everybody,

I recently used the WebView Gadget quite a lot.
Apparently there's a lot to configure under the hood IF you know there is a hood.
I have no idea how people even know how to do that. I haven't found any hints in the documentation about "GetGadgetAttribute(WebView, #PB_WebView_ICoreController)"

I have some code that I basically copied from viewtopic.php?p=631898#p631898 and tried to modify and I'm stuck. I tend to stick to using functions that are documented in the help file.
I realise that copying the Microsoft doc makes no sense, but I'm really having trouble understanding what I need to do in this case.

I hope somebody can drop a helpful hint. That would be awesome. Thank you! :)

So here's the essential code. According to the microsoft doc ( ;https://learn.microsoft.com/en-us/micro ... rarguments) it should accept a bool, but I get an IMA.
put_AllowSingleSignOnUsingOSPrimaryAccount
Sets the AllowSingleSignOnUsingOSPrimaryAccount property.
code: public HRESULT put_AllowSingleSignOnUsingOSPrimaryAccount(BOOL allow)

Code: Select all

Define Options.ICoreWebView2EnvironmentOptions
Options\put_AllowSingleSignOnUsingOSPrimaryAccount(#True) ;IMA "read error at address 0"
I'm sure there is some code missing, like loading the options or something similar to this line in the original post/code

Code: Select all

 If CoreWebView2\get_Settings(@Settings) <> #S_OK Or Settings = 0 : Goto Proc_Exit : EndIf


Here's the full code that runs when one removes the faulty, IMA-causing line

Code: Select all

;Code basically copied from User "breeze4me" - https://www.purebasic.fr/english/viewtopic.php?p=631898#p631898 
Procedure myFunc(WebView)
  Protected Result
  Protected Controller.ICoreWebView2Controller
  Protected CoreWebView2.ICoreWebView2

  Protected Options.ICoreWebView2EnvironmentOptions
  
  Options\put_AllowSingleSignOnUsingOSPrimaryAccount(#True) ;IMA "read error at address 0"
  
  ;https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2environmentoptions?view=webview2-1.0.3405.78#put_additionalbrowserarguments
  ;put_AllowSingleSignOnUsingOSPrimaryAccount
  ;Sets the AllowSingleSignOnUsingOSPrimaryAccount property.
  ;  public HRESULT put_AllowSingleSignOnUsingOSPrimaryAccount(BOOL allow)
  
  
  If GadgetType(WebView) <> #PB_GadgetType_WebView : ProcedureReturn 0 : EndIf
  
  Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
  If Controller = 0 : ProcedureReturn 0 : EndIf
  
  If Controller\get_CoreWebView2(@CoreWebView2) <> #S_OK Or CoreWebView2 = 0 : ProcedureReturn 0 : EndIf
  

  
  Proc_Exit:

  If CoreWebView2 : CoreWebView2\Release() : EndIf
  
  
  
  
  ProcedureReturn Result
EndProcedure

;----------------------------------------------------------------------------------------



OpenWindow(0, 0, 0, 1000, 900, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

WebViewGadget(2, 0, 35, 1000, 900)
SetGadgetText(2, "file://" + #PB_Compiler_Home + "examples/sources/Data/WebView/webview.html")

Debug myFunc(2)

Repeat 
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
User avatar
skywalk
Addict
Addict
Posts: 4276
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: WebView2 - IMA trying to change an option (ICoreWebView2xyz)

Post by skywalk »

Hi, this may be related to a bug I reported.
The code only fails with the DEBUGGER ON.

Code: Select all

Procedure IncrementCallback(JsonParameters$)
  Static Count
  Debug #PB_Compiler_Procedure +": " + JsonParameters$
  Count + 1
  ProcedureReturn UTF8(~"{ \"count\": "+Str(Count)+ "}")
EndProcedure

Procedure ComputeCallback(JsonParameters$)
  Debug #PB_Compiler_Procedure +": " + JsonParameters$
  Dim Parameters(0)
  ; Extract the parameters from the JSON
  ParseJSON(0, JsonParameters$)
  ExtractJSONArray(JSONValue(0), Parameters())
  Debug "Parameter 1: " + Parameters(0)
  Debug "Parameter 2: " + Parameters(1)
  ProcedureReturn UTF8(Str(Parameters(0) + Parameters(1)))
EndProcedure

OpenWindow(0, 100, 100, 400, 400, "Hello", #PB_Window_SystemMenu | #PB_Window_Invisible)
WebViewGadget(0, 0, 0, 400, 400)
SetGadgetText(0, "file://" + #PB_Compiler_Home + "examples/sources/Data/WebView/webview.html")
BindWebViewCallback(0, "increment", @IncrementCallback())
BindWebViewCallback(0, "compute", @ComputeCallback())
; Show the window once the webview has been fully loaded
HideWindow(0, #False)
Repeat 
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Derren
Enthusiast
Enthusiast
Posts: 319
Joined: Sat Jul 23, 2011 1:13 am
Location: Germany

Re: WebView2 - IMA trying to change an option (ICoreWebView2xyz)

Post by Derren »

Dang, I think you're onto something.

It doesn't crash with the Debugger disabled and when I tried to use DisableDebugger and EnableDebugger, I got an IMA on the DisableDebugger line

Code: Select all

DisableDebugger ;IMA on this line
Options\put_AllowSingleSignOnUsingOSPrimaryAccount(#True) ;IMA "read error at address 0"
EnableDebugger
There was another reply but now it's gone. It mentioned that you can't change the options after the gadget was created.

Seems like a dead end, then :(
breeze4me
Enthusiast
Enthusiast
Posts: 648
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: WebView2 - IMA trying to change an option (ICoreWebView2xyz)

Post by breeze4me »

The ICoreWebView2EnvironmentOptions interface must be created before any webview gadget is created and passed to it during creation. This cannot be done through usual methods and can only be passed via a hook.

The code below is based on this.
Please check if it works properly.

Edit:
Move the call to the put_AdditionalBrowserArguments method inside the functions.

Code: Select all

; https://github.com/webview/webview

;// The minimum WebView2 API version we need regardless of the SDK release
;// actually used. The number comes from the SDK release version,
;// e.g. 1.0.1150.38. To be safe the SDK should have a number that is greater
;// than or equal to this number. The Edge browser webview client must
;// have a number greater than or equal to this number.


EnableExplicit

CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
  #Lib_x86x64 = "86"
CompilerElse
  #Lib_x86x64 = "64"
CompilerEndIf

;Import "z:\Detours_x" + #Lib_x86x64 + ".lib"
Import "Detours.lib"
  DetourTransactionBegin.l()
  DetourTransactionCommit.l()
  DetourUpdateThread.l(hThread)
  DetourAttach.l(*ppPointer, pDetour)
  DetourDetach.l(*ppPointer, pDetour)
EndImport



DataSection
  IID_IUnknown:
  Data.l $00000000
  Data.w $0000, $0000
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46
  
  IID_ICoreWebView2EnvironmentOptions:
  Data.l $2fde08a8
  Data.w $1e9a, $4766
  Data.b $8c, $05, $95, $a9, $ce, $b9, $d1, $c5
  
  IID_ICoreWebView2EnvironmentOptions2:
  Data.l $FF85C98A
  Data.w $1BA7, $4A6B
  Data.b $90, $C8, $2B, $75, $2C, $89, $E9, $E2
  
  IID_ICoreWebView2EnvironmentOptions3:
  Data.l $4A5C436E
  Data.w $A9E3, $4A2E
  Data.b $89, $C3, $91, $0D, $35, $13, $F5, $CC
  
  IID_ICoreWebView2EnvironmentOptions4:
  Data.l $ac52d13f
  Data.w $0d38, $475a
  Data.b $9d, $ca, $87, $65, $80, $d6, $79, $3e
  
  IID_ICoreWebView2EnvironmentOptions5:
  Data.l $0AE35D64
  Data.w $C47F, $4464
  Data.b $81, $4E, $25, $9C, $34, $5D, $15, $01
  
  IID_ICoreWebView2EnvironmentOptions6:
  Data.l $57D29CC3
  Data.w $C84F, $42A0
  Data.b $B0, $E2, $EF, $FB, $D5, $E1, $79, $DE
  
EndDataSection



#CORE_WEBVIEW_TARGET_PRODUCT_VERSION = "123.0.2415.0"

Structure STRUC_IUnknownBase Align #PB_Structure_AlignC
  *pVtbl
  lRefCount.l
  
  *pQueryInterface
  *pAddRef
  *pRelease
EndStructure

Structure STRUC_ICoreWebView2EnvironmentOptions Extends STRUC_IUnknownBase
  *get_AdditionalBrowserArguments
  *put_AdditionalBrowserArguments
  *get_Language
  *put_Language
  *get_TargetCompatibleBrowserVersion
  *put_TargetCompatibleBrowserVersion
  *get_AllowSingleSignOnUsingOSPrimaryAccount
  *put_AllowSingleSignOnUsingOSPrimaryAccount
  
  sAdditionalBrowserArguments.s
  sLanguage.s
  sTargetCompatibleBrowserVersion.s
  lAllowSingleSignOnUsingOSPrimaryAccount.l
EndStructure

Structure STRUC_ICoreWebView2EnvironmentOptions2 Extends STRUC_IUnknownBase
  *get_ExclusiveUserDataFolderAccess
  *put_ExclusiveUserDataFolderAccess
EndStructure

Structure STRUC_ICoreWebView2EnvironmentOptions3 Extends STRUC_IUnknownBase
  *get_IsCustomCrashReportingEnabled
  *put_IsCustomCrashReportingEnabled
EndStructure

Structure STRUC_ICoreWebView2EnvironmentOptions4 Extends STRUC_IUnknownBase
  *GetCustomSchemeRegistrations
  *SetCustomSchemeRegistrations
EndStructure

Structure STRUC_ICoreWebView2EnvironmentOptions5 Extends STRUC_IUnknownBase
  *get_EnableTrackingPrevention
  *put_EnableTrackingPrevention
EndStructure

Structure STRUC_ICoreWebView2EnvironmentOptions6 Extends STRUC_IUnknownBase
  *get_AreBrowserExtensionsEnabled
  *put_AreBrowserExtensionsEnabled
EndStructure


Procedure MakeCoMemString(String.s, *Result.Long)
  Protected iResult, *Buffer, lStrBytes = StringByteLength(String)
  If *Result = 0 : ProcedureReturn 0 : EndIf
  *Result\l = #S_FALSE
  If lStrBytes > 0
    *Buffer = CoTaskMemAlloc_(lStrBytes + 2)
    If *Buffer
      If PokeS(*Buffer, String) > 0
        iResult = *Buffer
        *Result\l = #S_OK
      EndIf
      If *Result\l <> #S_OK
        CoTaskMemFree_(*Buffer)
      EndIf
    Else
      *Result\l = #E_OUTOFMEMORY
    EndIf 
  EndIf
  ProcedureReturn iResult
EndProcedure

Procedure.l ICoreWebView2EnvironmentOptions_QueryInterface(*this.STRUC_IUnknownBase, *riid.IID, *ppvObject.Integer)
  If *ppvObject And *riid
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID)) Or CompareMemory(*riid, ?IID_ICoreWebView2EnvironmentOptions, SizeOf(IID))
      *this\lRefCount + 1
      *ppvObject\i = *this
      
    ElseIf CompareMemory(*riid, ?IID_ICoreWebView2EnvironmentOptions2, SizeOf(IID))
      Debug "Req: Options2"
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
      
    ElseIf CompareMemory(*riid, ?IID_ICoreWebView2EnvironmentOptions3, SizeOf(IID))
      Debug "Req: Options3"
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
      
    ElseIf CompareMemory(*riid, ?IID_ICoreWebView2EnvironmentOptions4, SizeOf(IID))
      Debug "Req: Options4"
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
      
    ElseIf CompareMemory(*riid, ?IID_ICoreWebView2EnvironmentOptions5, SizeOf(IID))
      Debug "Req: Options5"
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
      
    ElseIf CompareMemory(*riid, ?IID_ICoreWebView2EnvironmentOptions6, SizeOf(IID))
      Debug "Req: Options6"
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
      
    Else
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
    EndIf
  Else
    ProcedureReturn #E_POINTER
  EndIf
  ProcedureReturn #S_OK
EndProcedure

Procedure.l ICoreWebView2EnvironmentOptions_AddRef(*this.STRUC_IUnknownBase)
  *this\lRefCount + 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2EnvironmentOptions_Release(*this.STRUC_IUnknownBase)
  *this\lRefCount - 1
  If *this\lRefCount <= 0
    FreeStructure(*this)
    Debug "EnvironmentOptions Freed"
    ProcedureReturn 0
  EndIf
  
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2EnvironmentOptions_get_AdditionalBrowserArguments(*this.STRUC_ICoreWebView2EnvironmentOptions, *value.Integer)
  Protected lResult.l = #S_FALSE
  Protected *Buffer
  
  Debug #PB_Compiler_Procedure
  
  If *value = 0 : ProcedureReturn #E_POINTER : EndIf
  *value\i = 0
  
  *Buffer = MakeCoMemString(*this\sAdditionalBrowserArguments, @lResult)
  If *Buffer : *value\i = *Buffer : EndIf
  
  ProcedureReturn lResult
EndProcedure

Procedure.l ICoreWebView2EnvironmentOptions_put_AdditionalBrowserArguments(*this.STRUC_ICoreWebView2EnvironmentOptions, *value)
  
  Debug #PB_Compiler_Procedure
  
  If *value = 0 : ProcedureReturn #E_POINTER : EndIf
  *this\sAdditionalBrowserArguments = PeekS(*value)
  ProcedureReturn #S_OK
EndProcedure

Procedure.l ICoreWebView2EnvironmentOptions_get_Language(*this.STRUC_ICoreWebView2EnvironmentOptions, *value.Integer)
  Protected lResult.l = #S_FALSE
  Protected *Buffer
  
  Debug #PB_Compiler_Procedure
  
  If *value = 0 : ProcedureReturn #E_POINTER : EndIf
  *value\i = 0
  
  *Buffer = MakeCoMemString(*this\sLanguage, @lResult)
  If *Buffer : *value\i = *Buffer : EndIf
  
  ProcedureReturn lResult
EndProcedure

Procedure.l ICoreWebView2EnvironmentOptions_put_Language(*this.STRUC_ICoreWebView2EnvironmentOptions, *value)
  
  Debug #PB_Compiler_Procedure
  
  If *value = 0 : ProcedureReturn #E_POINTER : EndIf
  *this\sLanguage = PeekS(*value)
  ProcedureReturn #S_OK
EndProcedure

Procedure.l ICoreWebView2EnvironmentOptions_get_TargetCompatibleBrowserVersion(*this.STRUC_ICoreWebView2EnvironmentOptions, *value.Integer)
  Protected lResult.l = #S_FALSE
  Protected *Buffer
  
  Debug #PB_Compiler_Procedure
  
  If *value = 0 : ProcedureReturn #E_POINTER : EndIf
  *value\i = 0
  
  *Buffer = MakeCoMemString(*this\sTargetCompatibleBrowserVersion, @lResult)
  If *Buffer : *value\i = *Buffer : EndIf
  
  ProcedureReturn lResult
EndProcedure

Procedure.l ICoreWebView2EnvironmentOptions_put_TargetCompatibleBrowserVersion(*this.STRUC_ICoreWebView2EnvironmentOptions, *value)
  
  Debug #PB_Compiler_Procedure
  
  If *value = 0 : ProcedureReturn #E_POINTER : EndIf
  *this\sTargetCompatibleBrowserVersion = PeekS(*value)
  ProcedureReturn #S_OK
EndProcedure

Procedure.l ICoreWebView2EnvironmentOptions_get_AllowSingleSignOnUsingOSPrimaryAccount(*this.STRUC_ICoreWebView2EnvironmentOptions, *allow.Long)
  
  Debug #PB_Compiler_Procedure
  
  If *allow = 0 : ProcedureReturn #E_POINTER : EndIf
  *allow\l = *this\lAllowSingleSignOnUsingOSPrimaryAccount
  ProcedureReturn #S_OK
EndProcedure

Procedure.l ICoreWebView2EnvironmentOptions_put_AllowSingleSignOnUsingOSPrimaryAccount(*this.STRUC_ICoreWebView2EnvironmentOptions, allow)
  
  Debug #PB_Compiler_Procedure
  
  *this\lAllowSingleSignOnUsingOSPrimaryAccount = allow
  ProcedureReturn #S_OK
EndProcedure

Procedure New_ICoreWebView2EnvironmentOptions()
  Protected *Buffer.STRUC_ICoreWebView2EnvironmentOptions = AllocateStructure(STRUC_ICoreWebView2EnvironmentOptions)
  
  If *Buffer
    With *Buffer
      \pVtbl = *Buffer + OffsetOf(STRUC_IUnknownBase\pQueryInterface)
      \lRefCount + 1
      \pQueryInterface = @ICoreWebView2EnvironmentOptions_QueryInterface()
      \pAddRef = @ICoreWebView2EnvironmentOptions_AddRef()
      \pRelease = @ICoreWebView2EnvironmentOptions_Release()
      \get_AdditionalBrowserArguments = @ICoreWebView2EnvironmentOptions_get_AdditionalBrowserArguments()
      \put_AdditionalBrowserArguments = @ICoreWebView2EnvironmentOptions_put_AdditionalBrowserArguments()
      \get_Language = @ICoreWebView2EnvironmentOptions_get_Language()
      \put_Language = @ICoreWebView2EnvironmentOptions_put_Language()
      \get_TargetCompatibleBrowserVersion = @ICoreWebView2EnvironmentOptions_get_TargetCompatibleBrowserVersion()
      \put_TargetCompatibleBrowserVersion = @ICoreWebView2EnvironmentOptions_put_TargetCompatibleBrowserVersion()
      \get_AllowSingleSignOnUsingOSPrimaryAccount = @ICoreWebView2EnvironmentOptions_get_AllowSingleSignOnUsingOSPrimaryAccount()
      \put_AllowSingleSignOnUsingOSPrimaryAccount = @ICoreWebView2EnvironmentOptions_put_AllowSingleSignOnUsingOSPrimaryAccount()
      
      \sTargetCompatibleBrowserVersion = #CORE_WEBVIEW_TARGET_PRODUCT_VERSION
      ;\lAllowSingleSignOnUsingOSPrimaryAccount = 0
    EndWith
  EndIf
  
  ProcedureReturn *Buffer
EndProcedure


Global g_Temp_ICoreWebView2EnvironmentOptions.ICoreWebView2EnvironmentOptions


; https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2365.46

; STDAPI CreateCoreWebView2EnvironmentWithOptions(PCWSTR browserExecutableFolder, PCWSTR userDataFolder, ICoreWebView2EnvironmentOptions* environmentOptions, ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler* environmentCreatedHandler);
; STDAPI GetAvailableCoreWebView2BrowserVersionString(PCWSTR browserExecutableFolder, LPWSTR* versionInfo);
; STDAPI CompareBrowserVersions(PCWSTR version1, PCWSTR version2, int* result);

; https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2365.46#createcorewebview2environmentwithoptions
; CreateCoreWebView2EnvironmentWithOptions(PCWSTR browserExecutableFolder, PCWSTR userDataFolder, ICoreWebView2EnvironmentOptions * environmentOptions, ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler * environmentCreatedHandler)
Prototype.l CreateCoreWebView2EnvironmentWithOptions(*browserExecutableFolder, *userDataFolder, *environmentOptions, *createdEnvironmentCallback)
Global CreateCoreWebView2EnvironmentWithOptions__.CreateCoreWebView2EnvironmentWithOptions

; https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2365.46#createwebviewenvironmentwithoptionsinternal
; CreateWebViewEnvironmentWithOptionsInternal(bool checkRunningInstance, int runtimeType, PCWSTR userDataFolder, IUnknown * environmentOptions, ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler * webViewEnvironmentCreatedHandler)
Prototype.l CreateWebViewEnvironmentWithOptionsInternal(checkRunningInstance.l, runtimeType.l, *userDataFolder, *environmentOptions, *webViewEnvironmentCreatedHandler)
Global CreateWebViewEnvironmentWithOptionsInternal__.CreateWebViewEnvironmentWithOptionsInternal

Procedure.l My_CreateWebViewEnvironmentWithOptionsInternal(checkRunningInstance.l, runtimeType.l, *userDataFolder, *environmentOptions.ICoreWebView2EnvironmentOptions, *webViewEnvironmentCreatedHandler)
  Protected lResult.l
  
;   ; Read the value you set in the environment variable below.
;   Protected sUserDataFolder.s = GetEnvironmentVariable("WEBVIEW2_USER_DATA_FOLDER")
  
  Debug "----------------------------------------"
  Debug #PB_Compiler_Procedure
  
;   If sUserDataFolder
;     
;     ; In this example, it is only used to show the "UserDataFolder", which is already specified.
;     If *userDataFolder
;       Debug "Previous UserDataFolder: " + PeekS(*userDataFolder)
;     EndIf
;     
;     ; Specify the new "UserDataFolder" that you obtained above.
;     *userDataFolder = @sUserDataFolder
;     Debug "Set new UserDataFolder: " + sUserDataFolder
;   EndIf
  
  
  If *environmentOptions = 0 And g_Temp_ICoreWebView2EnvironmentOptions
    *environmentOptions = g_Temp_ICoreWebView2EnvironmentOptions
    g_Temp_ICoreWebView2EnvironmentOptions = 0
    
    If *environmentOptions\put_AdditionalBrowserArguments(GetEnvironmentVariable("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS")) = #S_OK
      Debug "Set AdditionalBrowserArguments"
    EndIf
    
    Debug "Set ICoreWebView2EnvironmentOptions"
  EndIf
  
  Debug "----------------------------------------"
  
  
  ; Call the original unhooked function.
  lResult = CreateWebViewEnvironmentWithOptionsInternal__(checkRunningInstance, runtimeType, *userDataFolder, *environmentOptions, *webViewEnvironmentCreatedHandler)
  
  ProcedureReturn lResult
EndProcedure

Procedure.l My_CreateCoreWebView2EnvironmentWithOptions(*browserExecutableFolder, *userDataFolder, *environmentOptions.ICoreWebView2EnvironmentOptions, *createdEnvironmentCallback)
  Protected lResult.l
;   Protected sUserDataFolder.s = GetEnvironmentVariable("WEBVIEW2_USER_DATA_FOLDER")
  
  Debug "----------------------------------------"
  Debug #PB_Compiler_Procedure
  
;   If sUserDataFolder
;     If *userDataFolder
;       Debug "Previous UserDataFolder: " + PeekS(*userDataFolder)
;     EndIf
;     *userDataFolder = @sUserDataFolder
;     Debug "Set new UserDataFolder: " + sUserDataFolder
;   EndIf
  
  If *environmentOptions = 0 And g_Temp_ICoreWebView2EnvironmentOptions
    *environmentOptions = g_Temp_ICoreWebView2EnvironmentOptions
    g_Temp_ICoreWebView2EnvironmentOptions = 0
    
    If *environmentOptions\put_AdditionalBrowserArguments(GetEnvironmentVariable("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS")) = #S_OK
      Debug "Set AdditionalBrowserArguments"
    EndIf
    
    Debug "Set ICoreWebView2EnvironmentOptions"
  EndIf
  
  Debug "----------------------------------------"
  
  lResult = CreateCoreWebView2EnvironmentWithOptions__(*browserExecutableFolder, *userDataFolder, *environmentOptions, *createdEnvironmentCallback)
  
  ProcedureReturn lResult
EndProcedure

Procedure.s GetWebView2Path()
  Protected sResult.s
	Protected sSubkey.s = "SOFTWARE\Microsoft\EdgeUpdate\ClientState\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}"
	Protected hkey, *m, lDataBytes.l
	
	If RegOpenKeyEx_(#HKEY_LOCAL_MACHINE, sSubkey, 0, #KEY_READ | #KEY_WOW64_32KEY, @hkey) = #ERROR_SUCCESS
	  If RegQueryValueEx_(hkey, "EBWebView", 0, 0, *m, @lDataBytes) =	#ERROR_SUCCESS
	    If lDataBytes > 0
	      *m = AllocateMemory(lDataBytes)
	      If *m
	        If RegQueryValueEx_(hkey, "EBWebView", 0, 0, *m, @lDataBytes) =	#ERROR_SUCCESS
	          sResult = PeekS(*m)
	        EndIf
	        FreeMemory(*m)
	      EndIf
	    EndIf
	  EndIf
		RegCloseKey_(hkey)
	EndIf 
	
	ProcedureReturn sResult
EndProcedure




Define Lib_WV2, sPath.s

; First, we look in the registry to see if WebView2 is installed on the system.
sPath = GetWebView2Path()
If sPath
  
  ; If the "WebView2Loader.dll" file exists in the application folder,
  ; the WebGadget is created using the CreateCoreWebView2EnvironmentWithOptions function inside the "WebView2Loader.dll" file,
  ; otherwise, the WebGadget is created using the CreateWebViewEnvironmentWithOptionsInternal function inside the "EmbeddedBrowserWebView.dll" file at the path obtained above.
  
  ; We'll intercept the call to one of the two functions used to create the WebGadget.
  
  Lib_WV2 = OpenLibrary(#PB_Any, "WebView2Loader.dll")
  If Lib_WV2
    Debug "WebView2Loader.dll open."
    CreateCoreWebView2EnvironmentWithOptions__ = GetFunction(Lib_WV2, "CreateCoreWebView2EnvironmentWithOptions")
  Else
    Lib_WV2 = OpenLibrary(#PB_Any, sPath + "\EBWebView\x" + #Lib_x86x64 + "\EmbeddedBrowserWebView.dll")
    If Lib_WV2
      Debug "EmbeddedBrowserWebView.dll open."
      CreateWebViewEnvironmentWithOptionsInternal__ = GetFunction(Lib_WV2, "CreateWebViewEnvironmentWithOptionsInternal")
    EndIf
  EndIf
  
  ; Once you have the address of one of the two functions, try the hook.
  If CreateCoreWebView2EnvironmentWithOptions__ Or CreateWebViewEnvironmentWithOptionsInternal__
    ; https://github.com/microsoft/Detours/wiki/DetourTransactionBegin
    If DetourTransactionBegin() = #NO_ERROR
      
      ; https://github.com/microsoft/Detours/wiki/DetourUpdateThread
      If DetourUpdateThread(GetCurrentThread_()) = #NO_ERROR
        
        If CreateCoreWebView2EnvironmentWithOptions__
          ; https://github.com/microsoft/Detours/wiki/DetourAttach
          ; As a result of the function execution, the former variable stores the original function address before it was hooked.
          If DetourAttach(@CreateCoreWebView2EnvironmentWithOptions__, @My_CreateCoreWebView2EnvironmentWithOptions()) <> #NO_ERROR
            Debug "Error 0"
          EndIf
        EndIf
        
        If CreateWebViewEnvironmentWithOptionsInternal__
          If DetourAttach(@CreateWebViewEnvironmentWithOptionsInternal__, @My_CreateWebViewEnvironmentWithOptionsInternal()) <> #NO_ERROR
            Debug "Error 1"
          EndIf
        EndIf
        
        ; https://github.com/microsoft/Detours/wiki/DetourTransactionCommit
        DetourTransactionCommit()
      EndIf
    EndIf
    
  Else
    Debug "WebView2 function not found."
  EndIf
  
Else
  Debug "No WebView2 installed."
EndIf


OpenWindow(0, 0, 0, 1000, 900, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

; Strings returned by methods such as get_xxx in the ICoreWebView2EnvironmentOptions interface should be released by the caller using the CoTaskMemFree function. 
Define OptionsWVG_1.ICoreWebView2EnvironmentOptions = New_ICoreWebView2EnvironmentOptions()

If OptionsWVG_1
  Debug "ICoreWebView2EnvironmentOptions for Webview gadget #1: " + OptionsWVG_1
  
  If OptionsWVG_1\put_AllowSingleSignOnUsingOSPrimaryAccount(#True) = #S_OK
    Debug "OK : put_AllowSingleSignOnUsingOSPrimaryAccount"
  EndIf
  
  ; You must specify the interface in the global variable "g_Temp_ICoreWebView2EnvironmentOptions" immediately before creating any webview gadget.
  g_Temp_ICoreWebView2EnvironmentOptions = OptionsWVG_1
EndIf

WebViewGadget(1, 0, 35, 1000, 900)
SetGadgetText(1, "file://" + #PB_Compiler_Home + "examples/sources/Data/WebView/webview.html")

Define e

Repeat
  e = WaitWindowEvent()
  
Until e = #PB_Event_CloseWindow

If OptionsWVG_1
  OptionsWVG_1\Release()
EndIf

CloseLibrary(#PB_All)
User avatar
Derren
Enthusiast
Enthusiast
Posts: 319
Joined: Sat Jul 23, 2011 1:13 am
Location: Germany

Re: WebView2 - IMA trying to change an option (ICoreWebView2xyz)

Post by Derren »

Holy Cow! Amazing. It works.
THANK YOU!!!
Post Reply