Subject Re: ADOdatabase not working in signup.prg
From Gaetano <gaetanodd@hotmail.com>
Date Tue, 8 Sep 2020 08:18:57 +1000
Newsgroups dbase.getting-started
Attachment(s) adoapachefix.cc


Hi All.

Here is the fix for the ADO objects not working in compiled applications
under the Apache web server.

Credits:
•        Maurizio S for retrieving the issue #1017
(http://www.dbase.com/?s=1017, and search of “1017” on that page for
more details)
•        The author of the workaround code included in that issue #1017 is unknown

Summary of the issue:
If you include ADO objects in an Executable that is run on Apache, the
code will error out in windows versions from Vista 64 bits upward. This
is because the path for the ADO dll’s is under …\Program Files (x86)\...
and Apache cannot handle the parenthesis in that path name.

Solution:
Set a custom environment variable just before instantiating ADO objects.
Make sure to include the attached ADOapacheFix.cc file in the executable
and to call the initEnv() function shortly before instantiating the ADO
objects.


REQUIREMENT in addition to using this .cc file, Add the following line
to httpd.conf:

PassEnv CommonProgramFiles(x86)

Cheers,
Gaetano.



On 25/08/2020 01:13, Maurizio S. wrote:
> there is something involved with
> SetEnvironmentVariable
> using ADO on web server Apache
>
> on previous dBASE website, it was easy to find out this info
> I'm looking right now just to show you the correct page, but unable to
> find out
>
>
> tks
> Maurizio
>




/*

This Function fixes ADO DLLs not found by Apache on Win-64 bit system from Vista-64
upwards. If you include ADO objects in an Executable that is run on Apache,
the code will error out because the path for the ADO dlls is under \Program Files (x86)\...
and Apache cannot handle the parenthesis in that path name.

The following code generates a custom environment variable to work around the issue

This issue is covered in dBase issue #1017

call intenv() before every ADO object is instantiated
                
Usage:
set procedure to ADOapacheFix.cc additive

initEnv()
qADO=new ADOQUERY() or dADOdB= new ADODATABASE()
etc.

< and close procedure at the end of the PRG file>

close procedure adoapachefix.cc


Requirement for the code to work:
Add the following line at the end of your HTTPD.CONF file:
PassEnv CommonProgramFiles(x86)

The compiled version of this .cc file needs to be included in the executable when
BUILDing the app executable file (.exe or .dbw).

*/


function initEnv()
local cEnvStr, cEnvVar, cEnvVarNoParens

if OSVersion() >= 6 // Windows Vista is version 6.0
        
        if iswow64() // test if running on 64 bit version of Windows                
                if type("SetEnvironmentVariable") # "FP"
                        extern CLOGICAL SetEnvironmentVariable(CSTRING, CSTRING) kernel32 from "SetEnvironmentVariableA"
                endif

                cEnvVar = "CommonProgramFiles(x86)"
                cEnvVarNoParens = "CommonProgramFiles_x86_"

                // check if correct env.var already exists and has a value
                cEnvStr = getenv(cEnvVar)
                if empty(cEnvStr)
                // EnvVar with parens not found so must create it

                // check if modified env.var (without parens) already exists and has a value
                        cEnvStr = getenv(cEnvVarNoParens)
                        if empty(cEnvStr)
                                // cEnvVarNoParens not found use default value for it
                                cEnvStr = "C:\Program Files (x86)\Common Files"
                        else
                                // otherwise cEnvVarNoParens exists and has a value
                        endif

// Create and set value of env.var (with parens)
                        bResult = SetEnvironmentVariable(cEnvVar, cEnvStr)
                endif
        endif
endif

function IsWow64
        local lIsWow64

        lIsWow64 = false

        if type("GetCurrentProcess") # "FP"
        extern CHANDLE GetCurrentProcess( CVOID ) kernel32
        endif

        if type("IsWow64Process") # "FP"
        extern CLOGICAL IsWow64Process(CHANDLE, CPTR CLOGICAL) kernel32
        endif

        if type("IsWow64Process") = "FP"
        // Make sure extern worked for retrieving this function pointer
        // Because older versions of windows do not contain this function
        // From MSDN, minimum supported operating systems are:
        // Client OSs: Win XP SP2, Vista
        // Server OSs: Windows Server 2003 with SP1, Windows Server 2008
        IsWow64Process(GetCurrentProcess(), lIsWow64)
        endif

        return lIsWow64

function OSVersion
        local cVersion
        cVersion = OS()
return val(ltrim(substr(cversion,rat(" ",cVersion))))