E9.2 Performing SQL statements on ODBC OneWorld ODA causes Memory Access Violation

Edgars Tjarve

Member
Hello!

Our company has a C# application, that attempts to connect to DSN of OneWorld Oda (JDEOWODA.dll V2.0.0.0) to get data from tables. We currently have Installed JDEdwards version 9.2.6.3 64Bit Client. Application is being developed on Win64 bit machine and for 64Bits. We are able to connect to driver just fine (when developer is not logged in, a JDE login form pops up) and upon entering credentials we get a successful connection. We are even able to use SQLTables (ODBC32.dll function method) to retrieve all tables that connection can see. But when we are trying to write any query and give it to our connection (any table, any request), we get a crash with error "System.AccessViolationException, Attempted to read or write protected memory" at ODBC functions SQLExecureDirectW and SQLPrepareW. It seems that we are doing everything correctly (setting ODBC version to "2" before connecting, setting handles correctly, tried various queries. And code used to work before (was changed to a different method but now we want to return to this method)), but couldn't find the cause of this issue. Does anyone have solved this issue or could help to put us on a right path?

P.S. We are even trying to test this with ODBCTest application (from Microsoft) but issue occurs there too
 
ODA was never a “robust” product. I also thought it had been put down years ago.
Dump it and go directly against the database.
 
It seems like it. Would be great to find out how Patwels' ObjectBrowser handles user login information and connection to databases.
 
Code below is ANSI C that you can compile outside of JDE in Visual Studio project - on fat client. All you need to do is to setup additional include directories pointing to <jde_install_path>\system\include, <jde_install_path>\system\includeV, <jde_install_path>\DV920\include64 and additional link directories to <jde_install_path>\system\Lib64 . Preprocessor definitions should include KERNEL;JDENV_PC; Structure member alignment needs to be se to 8 (on 64 bits) or 1 (32 bits). Calling convention needs to be stdcall.
Additional linker dependencies need to include jdel.lib;jdekrnl.lib;jdeunicode.lib. Additionally you can use any of JDB_* APIs like JDB_OpenTable, JDB_Fetch and so on. For C# you can write C helper DLL to facilitate calls.

int _cdecl main(int argc, char *argv[])
{
JDEDB_RESULT rcode = JDEDB_PASSED;

HENV hEnv = NULL;
HUSER hUser = NULL;
LPCG_BHVR lpVoid = NULL;
LPBHVRCOM lpBhvrCom = NULL;
ERROR_EVENT_KEY EventKeyLocal;
/* BSFN DS */
DSD9800100 dsD9800100 = {0};

if ((rcode = JDB_InitEnv(&hEnv)) != JDEDB_PASSED)
{
jdePrintf(_J("JDB_InitEnvOvr failed\n "));
return (2);
}

/* With a valid HENV you can create a user handle. */
if ((rcode = JDB_InitUser(hEnv, &hUser, NULL, JDEDB_COMMIT_AUTO)) != JDEDB_PASSED)
{
jdePrintf(_J("JDB_InitUser failed\n"));
return (2);
}

// Set up the lpBhvrCom amd lpVoid objects.
jdeCreateBusinessFunctionParms(hUser, &lpBhvrCom,(LPVOID*) &lpVoid);
lpVoid->lpHdr = jdeErrorInitializeEx();
lpVoid->lpErrorEventKey = (LPERROR_EVENT_KEY) jdeAlloc(COMMON_POOL,sizeof(ERROR_EVENT_KEY), MEM_ZEROINIT | MEM_FIXED);
lpVoid->lpHdr->nCurDisplayed = -1;
lpBhvrCom->lpObj->lpFormHdr = lpVoid->lpHdr;
EventKeyLocal.hwndCtrl = NULL;
EventKeyLocal.iGridCol = 0;
EventKeyLocal.iGridRow = 0;
EventKeyLocal.wEvent = 1;
lpBhvrCom->lpEventKey = (LPVOID)&EventKeyLocal;

jdeCallObject (_J("GetAuditInfo"), NULL,lpBhvrCom, lpVoid,(void*)&dsD9800100, (LPCALLMAP)NULL,(int)0, (JCHAR *)NULL, (JCHAR *)NULL, (int)0);
jdePrintf(_J("Returned values are \n User:%s\n Workstation:%s\n"),dsD9800100.szUserName,dsD9800100.szWorkstation_UserId);

/* now clean up handles */
if (lpVoid)
{
jdeFree(lpVoid->lpErrorEventKey);
jdeErrorTerminateEx(lpVoid->lpHdr);
jdeFreeBusinessFunctionParms(lpBhvrCom,lpVoid);
lpBhvrCom = NULL;
lpVoid = NULL;
}

if (hUser)
{
JDB_FreeUser(hUser);
}

if (hEnv)
{
JDB_FreeEnv(hEnv);
printf("Done\n");
};

return 0;
}
 
Back
Top