SQLGetCursorName

decompiled_code:
__int64 __fastcall SQLGetCursorName(__int64 a1, void *a2, __int16 a3, const void *a4)
{
unsigned int v4; // ebp
__int64 v6; // rax
__int64 (__fastcall *v7)(_QWORD, void *, _QWORD, const void *); // r14
__int16 v8; // r14
void *v10; // rax
void *v11; // r15
__int64 (__fastcall *v12)(_QWORD, const void *, _QWORD, const void *); // r8
const char *v13; // rbp
const char *v14; // rax
_BYTE v15[296]; // [rsp+0h] [rbp-128h] BYREF

LOWORD(v4) = a3;
if ( !(unsigned int)_validate_stmt() )
{
dm_log_write("SQLGetCursorName.c", 161LL, 0LL, 0LL, "Error: SQL_INVALID_HANDLE");
return 4294967294LL;
}
function_entry(a1);
if ( log_info[4] )
{
sprintf(
(char *)(a1 + 16),
"\n\t\tEntry:\n\t\t\tStatement = %p\n\t\t\tCursor Name = %p\n\t\t\tBuffer Length = %d\n\t\t\tName Length= %p",
(const void *)a1,
a2,
(unsigned int)(__int16)v4,
a4);
dm_log_write("SQLGetCursorName.c", 184LL, 0LL, 0LL, a1 + 16);
}
thread_protect(3LL, a1);
if ( (unsigned int)(*(_DWORD *)(a1 + 1040) - 8) <= 4 )
{
dm_log_write("SQLGetCursorName.c", 218LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1088, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
v6 = *(_QWORD *)(a1 + 1048);
if ( *(_DWORD *)(v6 + 1456) )
{
v7 = *(__int64 (__fastcall **)(_QWORD, void *, _QWORD, const void *))(*(_QWORD *)(v6 + 1320) + 2472LL);
if ( !v7 )
{
dm_log_write("SQLGetCursorName.c", 237LL, 0LL, 0LL, "Error: IM001");
_post_internal_error(a1 + 1088, 42LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( a2 && (__int16)v4 > 0 )
{
v4 = (__int16)v4;
v10 = malloc(2LL * ((__int16)v4 + 1));
v11 = v10;
if ( v10 )
{
v8 = v7(*(_QWORD *)(a1 + 1056), v10, (unsigned int)(__int16)v4, a4);
if ( (v8 & 0xFFFE) == 0 )
unicode_to_ansi_copy(a2, (unsigned int)(__int16)v4, v11, -3LL, *(_QWORD *)(a1 + 1048));
free(v11);
goto LABEL_20;
}
}
else
{
v4 = (__int16)v4;
}
v8 = v7(*(_QWORD *)(a1 + 1056), a2, v4, a4);
}
else
{
v12 = *(__int64 (__fastcall **)(_QWORD, const void *, _QWORD, const void *))(*(_QWORD *)(v6 + 1320) + 2464LL);
if ( !v12 )
{
dm_log_write("SQLGetCursorName.c", 275LL, 0LL, 0LL, "Error: IM001");
_post_internal_error(a1 + 1088, 42LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
v8 = v12(*(_QWORD *)(a1 + 1056), a2, (unsigned int)(__int16)v4, a4);
}
LABEL_20:
if ( log_info[4] )
{
v13 = (const char *)_sdata_as_string(v15, 1LL, a4, a2);
v14 = (const char *)_get_return_status((unsigned int)v8, v15);
sprintf((char *)(a1 + 16), "\n\t\tExit:[%s] \n\t\t\tCursor Name = %s", v14, v13);
dm_log_write("SQLGetCursorName.c", 304LL, 0LL, 0LL, a1 + 16);
}
return function_return_ex(3LL, a1, (unsigned int)v8, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, void *a2, __int16 a3, const void *a4)
{
unsigned int v4; // ebp
__int64 v6; // rax
__int64 (__fastcall *v7)(_QWORD, void *, _QWORD, const void *); // r14
__int16 v8; // r14
void *v10; // rax
void *v11; // r15
__int64 (__fastcall *v12)(_QWORD, const void *, _QWORD, const void *); // r8
const char *v13; // rbp
const char *v14; // rax
_BYTE v15[296]; // [rsp+0h] [rbp-128h] BYREF

LOWORD(v4) = a3;
if ( !(unsigned int)_validate_stmt() )
{
dm_log_write("SQLGetCursorName.c", 161LL, 0LL, 0LL, "Error: SQL_INVALID_HANDLE");
return 4294967294LL;
}
function_entry(a1);
if ( log_info[4] )
{
sprintf(
(char *)(a1 + 16),
"\n\t\tEntry:\n\t\t\tStatement = %p\n\t\t\tCursor Name = %p\n\t\t\tBuffer Length = %d\n\t\t\tName Length= %p",
(const void *)a1,
a2,
(unsigned int)(__int16)v4,
a4);
dm_log_write("SQLGetCursorName.c", 184LL, 0LL, 0LL, a1 + 16);
}
thread_protect(3LL, a1);
if ( (unsigned int)(*(_DWORD *)(a1 + 1040) - 8) <= 4 )
{
dm_log_write("SQLGetCursorName.c", 218LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1088, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
v6 = *(_QWORD *)(a1 + 1048);
if ( *(_DWORD *)(v6 + 1456) )
{
v7 = *(__int64 (__fastcall **)(_QWORD, void *, _QWORD, const void *))(*(_QWORD *)(v6 + 1320) + 2472LL);
if ( !v7 )
{
dm_log_write("SQLGetCursorName.c", 237LL, 0LL, 0LL, "Error: IM001");
_post_internal_error(a1 + 1088, 42LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( a2 && (__int16)v4 > 0 )
{
v4 = (__int16)v4;
v10 = malloc(2LL * ((__int16)v4 + 1));
v11 = v10;
if ( v10 )
{
v8 = v7(*(_QWORD *)(a1 + 1056), v10, (unsigned int)(__int16)v4, a4);
if ( (v8 & 0xFFFE) == 0 )
unicode_to_ansi_copy(a2, (unsigned int)(__int16)v4, v11, -3LL, *(_QWORD *)(a1 + 1048));
free(v11);
goto LABEL_20;
}
}
else
{
v4 = (__int16)v4;
}
v8 = v7(*(_QWORD *)(a1 + 1056), a2, v4, a4);
}
else
{
v12 = *(__int64 (__fastcall **)(_QWORD, const void *, _QWORD, const void *))(*(_QWORD *)(v6 + 1320) + 2464LL);
if ( !v12 )
{
dm_log_write("SQLGetCursorName.c", 275LL, 0LL, 0LL, "Error: IM001");
_post_internal_error(a1 + 1088, 42LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
v8 = v12(*(_QWORD *)(a1 + 1056), a2, (unsigned int)(__int16)v4, a4);
}
LABEL_20:
if ( log_info[4] )
{
v13 = (const char *)_sdata_as_string(v15, 1LL, a4, a2);
v14 = (const char *)_get_return_status((unsigned int)v8, v15);
sprintf((char *)(a1 + 16), "\n\t\tExit:[%s] \n\t\t\tCursor Name = %s", v14, v13);
dm_log_write("SQLGetCursorName.c", 304LL, 0LL, 0LL, a1 + 16);
}
return function_return_ex(3LL, a1, (unsigned int)v8, 0LL);
}

original_code:
RETCODE SQLGetCursorName(
        HSTMT hstmt,
        UCHAR *szCursor,
        SWORD cbCursorMax,
        SWORD *pcbCursor)
{
static char* const func="SQLGetCursorName";
StatementClass *stmt = (StatementClass *) hstmt;
int len = 0;
RETCODE result;
mylog("SQLGetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d, pcbCursor=%u\n", hstmt, szCursor, cbCursorMax, pcbCursor);
 if ( ! stmt) {
  SC_log_error(func, "", ((void *)0));
  return (-2);
 }
 if ( stmt->cursor_name[0] == '\0') {
  SC_set_error(stmt, 18, "No Cursor name available");
  SC_log_error(func, "", stmt);
  return (-1);
 }
 result = 0;
 len = strlen(stmt->cursor_name);
 if (szCursor) {
  strncpy_null((char*)szCursor, (char*)stmt->cursor_name, cbCursorMax);
  if (len >= cbCursorMax) {
   result = 1;
   SC_set_error(stmt, -2, "The buffer was too small for the result.");
  }
 }
 if (pcbCursor)
  *pcbCursor = len;
 return result;
}

canonical_original_code:
short SQLGetCursorName(void *hstmt, unsigned char *szCursor, short cbCursorMax, short *pcbCursor)
{
static char *func = "SQLGetCursorName";
struct StatementClass_ *stmt = (StatementClass *) hstmt;
int len = 0;
short result;
mylog("SQLGetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d, pcbCursor=%u\n", hstmt, szCursor, cbCursorMax, pcbCursor);
 if ( ! stmt) {
  SC_log_error(func, "", ((void *)0));
  return (-2);
 }
 if ( stmt->cursor_name[0] == '\0') {
  SC_set_error(stmt, 18, "No Cursor name available");
  SC_log_error(func, "", stmt);
  return (-1);
 }
 result = 0;
 len = strlen(stmt->cursor_name);
 if (szCursor) {
  strncpy_null((char *)szCursor, (char *)stmt->cursor_name, cbCursorMax);
  if (len >= cbCursorMax) {
   result = 1;
   SC_set_error(stmt, -2, "The buffer was too small for the result.");
  }
 }
 if (pcbCursor)
  *pcbCursor = len;
 return result;
}

variable_types:
hstmt
void *

variable_types:
szCursor
unsigned char *

variable_types: cbCursorMax short

variable_types:
pcbCursor
short *

variable_types:
func
char *

variable_types: len int

user_defined_types: enum STMT_Status { STMT_ALLOCATED=0, STMT_READY=1, STMT_PREMATURE=2, STMT_FINISHED=3, STMT_EXECUTING=4 }

user_defined_types: struct ConnectionClass_ { void *henv; struct StatementOptions_ stmtOptions; char *__error_message; int __error_number; enum CONN_Status status; struct ConnInfo connInfo; struct StatementClass_ **stmts; int num_stmts; struct SocketClass_ *sock; int lobj_type; int ntables; struct col_info **col_info; long translation_option; void *translation_handle; int (*DataSourceToDriver)(unsigned long, short, void *, long, void *, long, long *, unsigned char *, short, short *); int (*DriverToDataSource)(unsigned long, short, void *, long, void *, long, long *, unsigned char *, short, short *); short driver_version; char transact_status; char errormsg_created; char pg_version[128]; float pg_version_number; short pg_version_major; short pg_version_minor; char ms_jet; char unicode; char result_uncommitted; char schema_support; char *client_encoding; char *server_encoding; int ccsc; int be_pid; int be_key; unsigned int isolation; char *current_schema; int num_discardp; char **discardp; }


repo: xiaotmiaomiao/unixODBC-SPEC

decompiled_code:
__int64 __fastcall TL_Destructor(void *ptr)
{
void **v1; // r13
int i; // ebx
void **v4; // rbp
void **v5; // rbx

mylog("TupleList: in DESTRUCTOR\n");
v1 = (void **)*((_QWORD *)ptr + 1);
if ( v1 )
{
while ( 1 )
{
v4 = v1 + 3;
for ( i = 0; *(_DWORD *)ptr > i; v4 += 2 )
{
if ( *v4 )
free(*v4);
++i;
}
v5 = (void **)v1[1];
free(v1);
if ( !v5 )
break;
v1 = v5;
}
}
free(ptr);
return mylog("TupleList: exit DESTRUCTOR\n");
}

canonical_decompiled_code:
__int64 __fastcall func0(void *ptr)
{
void **v1; // r13
int i; // ebx
void **v4; // rbp
void **v5; // rbx

mylog("TupleList: in DESTRUCTOR\n");
v1 = (void **)*((_QWORD *)ptr + 1);
if ( v1 )
{
while ( 1 )
{
v4 = v1 + 3;
for ( i = 0; *(_DWORD *)ptr > i; v4 += 2 )
{
if ( *v4 )
free(*v4);
++i;
}
v5 = (void **)v1[1];
free(v1);
if ( !v5 )
break;
v1 = v5;
}
}
free(ptr);
return mylog("TupleList: exit DESTRUCTOR\n");
}

original_code:
void
TL_Destructor(TupleListClass *self)
{
int lf;
TupleNode *node, *tp;
 mylog("TupleList: in DESTRUCTOR\n");
    node = self->list_start;
    while(node != ((void *)0)) {
        for (lf=0; lf < self->num_fields; lf++)
            if (node->tuple[lf].value != ((void *)0)) {
                free(node->tuple[lf].value);
            }
        tp = node->next;
        free(node);
        node = tp;
    }
 free(self);
 mylog("TupleList: exit DESTRUCTOR\n");
}

canonical_original_code:
void TL_Destructor(struct TupleListClass_ *self)
{
int lf;
struct TupleNode_ *node; struct TupleNode_ *tp;
 mylog("TupleList: in DESTRUCTOR\n");
    node = self->list_start;
    while(node != ((void *)0)) {
        for (lf=0; lf < self->num_fields; lf++)
            if (node->tuple[lf].value != ((void *)0)) {
                free(node->tuple[lf].value);
            }
        tp = node->next;
        free(node);
        node = tp;
    }
 free(self);
 mylog("TupleList: exit DESTRUCTOR\n");
}

variable_types: struct TupleListClass_ { int num_fields; int num_tuples; struct TupleNode_ { struct TupleNode_ *prev; struct TupleField_ { int len; void *value; } tuple[1]; } *list_start; int last_indexed; } *

variable_types: lf int

return_type: void

user_defined_types: struct TupleListClass_ { int num_fields; int num_tuples; struct TupleNode_ *list_start; int last_indexed; }

user_defined_types: struct TupleNode_ { struct TupleNode_ *prev; struct TupleField_ tuple[1]; }


original_code:
void *
TL_get_fieldval(TupleListClass *self, int tupleno, short fieldno)
{
int lf;
int delta, from_end;
char end_is_closer, start_is_closer;
TupleNode *rv;
 if (self->last_indexed == -1)
  return ((void *)0);
 if ((tupleno >= self->num_tuples) || (tupleno < 0))
  return ((void *)0);
 if ((fieldno >= self->num_fields) || (fieldno < 0))
  return ((void *)0);
 if (tupleno == self->last_indexed)
  return self->lastref->tuple[fieldno].value;
 delta = tupleno - self->last_indexed;
 from_end = (self->num_tuples - 1) - tupleno;
 start_is_closer = labs(delta) > tupleno;
 end_is_closer = labs(delta) > from_end;
 if (end_is_closer) {
  rv = self->list_end;
  for (lf=0; lf < from_end; lf++)
   rv = rv->prev;
 } else if (start_is_closer) {
  rv = self->list_start;
  for (lf=0; lf < tupleno; lf++)
   rv = rv->next;
 } else {
  rv = self->lastref;
  if (delta < 0) {
   for(lf=0; lf < (-1)*delta; lf++)
    rv = rv->prev;
  } else {
   for (lf=0; lf < delta; lf++)
   rv = rv->next;
  }
 }
 self->lastref = rv;
 self->last_indexed = tupleno;
 return rv->tuple[fieldno].value;
}

canonical_original_code:
void *TL_get_fieldval(struct TupleListClass_ *self, int tupleno, short fieldno)
{
int lf;
int delta; int from_end;
char end_is_closer; char start_is_closer;
struct TupleNode_ *rv;
 if (self->last_indexed == -1)
  return ((void *)0);
 if ((tupleno >= self->num_tuples) || (tupleno < 0))
  return ((void *)0);
 if ((fieldno >= self->num_fields) || (fieldno < 0))
  return ((void *)0);
 if (tupleno == self->last_indexed)
  return self->lastref->tuple[fieldno].value;
 delta = tupleno - self->last_indexed;
 from_end = (self->num_tuples - 1) - tupleno;
 start_is_closer = labs(delta) > tupleno;
 end_is_closer = labs(delta) > from_end;
 if (end_is_closer) {
  rv = self->list_end;
  for (lf=0; lf < from_end; lf++)
   rv = rv->prev;
 } else if (start_is_closer) {
  rv = self->list_start;
  for (lf=0; lf < tupleno; lf++)
   rv = rv->next;
 } else {
  rv = self->lastref;
  if (delta < 0) {
   for(lf=0; lf < (-1)*delta; lf++)
    rv = rv->prev;
  } else {
   for (lf=0; lf < delta; lf++)
   rv = rv->next;
  }
 }
 self->lastref = rv;
 self->last_indexed = tupleno;
 return rv->tuple[fieldno].value;
}

variable_types: tupleno int

variable_types: fieldno short

variable_types: delta int

variable_types: struct TupleNode_ { struct TupleNode_ *prev; struct TupleField_ { int len; void *value; } tuple[1]; } *

return_type: void *


original_code:
char
TL_add_tuple(TupleListClass *self, TupleNode *new_field)
{
 new_field->prev = ((void *)0);
 new_field->next = ((void *)0);
 if (self->list_start == ((void *)0)) {
  self->list_start = new_field;
  self->list_end = new_field;
  self->lastref = new_field;
  self->last_indexed = 0;
 } else {
  self->list_end->next = new_field;
  new_field->prev = self->list_end;
  self->list_end = new_field;
 }
 self->num_tuples++;
 return 1;
}

canonical_original_code:
char TL_add_tuple(struct TupleListClass_ *self, struct TupleNode_ *new_field)
{
 new_field->prev = ((void *)0);
 new_field->next = ((void *)0);
 if (self->list_start == ((void *)0)) {
  self->list_start = new_field;
  self->list_end = new_field;
  self->lastref = new_field;
  self->last_indexed = 0;
 } else {
  self->list_end->next = new_field;
  new_field->prev = self->list_end;
  self->list_end = new_field;
 }
 self->num_tuples++;
 return 1;
}

return_type: char

user_defined_types: struct TupleField_ { int len; void *value; }


decompiled_code:
void __fastcall dconn_get_connect_attributes(char *s, void *a2)
{
char *v2; // r14
char *v3; // rdi
char *v4; // rbx
char *v5; // rax
const char *v6; // rbp
char *v7; // rax

memset(a2, 0, 0x2851uLL);
v2 = strdup(s);
mylog("our_connect_string = '%s'\n", v2);
v3 = v2;
while ( 1 )
{
v5 = strtok(v3, ";");
v6 = v5;
if ( !v5 )
break;
v7 = strchr(v5, 61);
v3 = v7;
if ( v7 )
{
*v7 = 0;
v4 = v7 + 1;
mylog("attribute = '%s', value = '%s'\n", v6, v7 + 1);
copyAttributes(a2, v6, v4);
v3 = 0LL;
}
}
free(v2);
}

canonical_decompiled_code:
void __fastcall func0(char *s, void *a2)
{
char *v2; // r14
char *v3; // rdi
char *v4; // rbx
char *v5; // rax
const char *v6; // rbp
char *v7; // rax

memset(a2, 0, 0x2851uLL);
v2 = strdup(s);
mylog("our_connect_string = '%s'\n", v2);
v3 = v2;
while ( 1 )
{
v5 = strtok(v3, ";");
v6 = v5;
if ( !v5 )
break;
v7 = strchr(v5, 61);
v3 = v7;
if ( v7 )
{
*v7 = 0;
v4 = v7 + 1;
mylog("attribute = '%s', value = '%s'\n", v6, v7 + 1);
copyAttributes(a2, v6, v4);
v3 = 0LL;
}
}
free(v2);
}

original_code:
void dconn_get_connect_attributes(UCHAR *connect_string, ConnInfo *ci)
{
char *our_connect_string;
char *pair, *attribute, *value, *equals;
char *strtok_arg;
 memset(ci, 0, sizeof(ConnInfo));
 our_connect_string = strdup((char*)connect_string);
 strtok_arg = our_connect_string;
 mylog("our_connect_string = '%s'\n", our_connect_string);
 while(1) {
  pair = strtok(strtok_arg, ";");
  if(strtok_arg) {
   strtok_arg = 0;
  }
  if(!pair) {
   break;
  }
  equals = strchr(pair, '=');
  if ( ! equals)
   continue;
  *equals = '\0';
  attribute = pair;
  value = equals + 1;
  mylog("attribute = '%s', value = '%s'\n", attribute, value);
  if( !attribute || !value)
   continue;
  copyAttributes(ci, attribute, value);
 }
 free(our_connect_string);
}

canonical_original_code:
void dconn_get_connect_attributes(unsigned char *connect_string, struct ConnInfo *ci)
{
char *our_connect_string;
char *pair; char *attribute; char *value; char *equals;
char *strtok_arg;
 memset(ci, 0, sizeof(ConnInfo));
 our_connect_string = strdup((char *)connect_string);
 strtok_arg = our_connect_string;
 mylog("our_connect_string = '%s'\n", our_connect_string);
 while(1) {
  pair = strtok(strtok_arg, ";");
  if(strtok_arg) {
   strtok_arg = 0;
  }
  if(!pair) {
   break;
  }
  equals = strchr(pair, '=');
  if ( ! equals)
   continue;
  *equals = '\0';
  attribute = pair;
  value = equals + 1;
  mylog("attribute = '%s', value = '%s'\n", attribute, value);
  if( !attribute || !value)
   continue;
  copyAttributes(ci, attribute, value);
 }
 free(our_connect_string);
}

variable_types: struct ConnInfo { char dsn[256]; char desc[256]; char driver[256]; char server[256]; char database[256]; char username[256]; char password[256]; char conn_settings[4096]; char protocol[10]; char port[10]; char uds[4096]; char onlyread[10]; char fake_oid_index[10]; char show_oid_column[10]; char row_versioning[10]; char show_system_tables[10]; char translation_dll[256]; char translation_option[10]; char focus_password; } *

variable_types:
pair
char *

variable_types:
attribute
char *

variable_types:
value
char *

variable_types:
equals
char *


SQLDriverConnect

decompiled_code:
__int64 __fastcall SQLDriverConnect(_BYTE *a1, __int64 a2, __int64 a3, __int16 a4, const char *a5, __int16 a6, _WORD *a7, unsigned __int16 a8)
{
unsigned int v11; // er12
int v12; // eax
int v13; // er13
char v16[5]; // [rsp+1Bh] [rbp-203Dh] BYREF
char s[4096]; // [rsp+20h] [rbp-2038h] BYREF
char v18[4152]; // [rsp+1020h] [rbp-1038h] BYREF

mylog("%s: entering...\n", "SQLDriverConnect");
if ( a1 )
{
make_string(a3, (unsigned int)a4, v18);
mylog("**** SQLDriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", a8, v18);
qlog("conn=%u, SQLDriverConnect( in)='%s', fDriverCompletion=%d\n", a1, v18, a8);
dconn_get_connect_attributes(v18, a1 + 64);
getDSNinfo(a1 + 64, 0LL);
getDSNdefaults(a1 + 64);
CC_initialize_pg_version(a1);
v16[0] = 0;
a1[10384] = 0;
v11 = 100;
if ( a1[1344] && a1[832] && a1[1088] && a1[5962] )
{
v12 = (char)CC_connect(a1, 0LL, v16);
if ( v12 < 0 )
{
v11 = -1;
if ( !a8 )
CC_log_error("SQLDriverConnect", "Need password but Driver_NoPrompt", a1);
}
else if ( v12 )
{
makeConnectString(s, a1 + 64);
v13 = strlen(s);
v11 = 0;
if ( a5 )
{
strncpy_null(a5, s, (unsigned int)a6);
if ( a6 <= v13 )
{
CC_set_error(a1, 215LL, "The buffer was too small for the result.");
v11 = 1;
}
}
if ( a7 )
*a7 = v13;
mylog("szConnStrOut = '%s'\n", a5);
qlog("conn=%u, SQLDriverConnect(out)='%s'\n", a1, a5);
mylog("SQLDRiverConnect: returning %d\n", (unsigned int)(__int16)v11);
}
else
{
CC_log_error("SQLDriverConnect", "Error from CC_Connect", a1);
v11 = -1;
}
}
}
else
{
CC_log_error("SQLDriverConnect", &LC5, 0LL);
v11 = -2;
}
return v11;
}

canonical_decompiled_code:
__int64 __fastcall func1(_BYTE *a1, __int64 a2, __int64 a3, __int16 a4, const char *a5, __int16 a6, _WORD *a7, unsigned __int16 a8)
{
unsigned int v11; // er12
int v12; // eax
int v13; // er13
char v16[5]; // [rsp+1Bh] [rbp-203Dh] BYREF
char s[4096]; // [rsp+20h] [rbp-2038h] BYREF
char v18[4152]; // [rsp+1020h] [rbp-1038h] BYREF

mylog("%s: entering...\n", "SQLDriverConnect");
if ( a1 )
{
make_string(a3, (unsigned int)a4, v18);
mylog("**** SQLDriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", a8, v18);
qlog("conn=%u, SQLDriverConnect( in)='%s', fDriverCompletion=%d\n", a1, v18, a8);
func0(v18, a1 + 64);
getDSNinfo(a1 + 64, 0LL);
getDSNdefaults(a1 + 64);
CC_initialize_pg_version(a1);
v16[0] = 0;
a1[10384] = 0;
v11 = 100;
if ( a1[1344] && a1[832] && a1[1088] && a1[5962] )
{
v12 = (char)CC_connect(a1, 0LL, v16);
if ( v12 < 0 )
{
v11 = -1;
if ( !a8 )
CC_log_error("SQLDriverConnect", "Need password but Driver_NoPrompt", a1);
}
else if ( v12 )
{
makeConnectString(s, a1 + 64);
v13 = strlen(s);
v11 = 0;
if ( a5 )
{
strncpy_null(a5, s, (unsigned int)a6);
if ( a6 <= v13 )
{
CC_set_error(a1, 215LL, "The buffer was too small for the result.");
v11 = 1;
}
}
if ( a7 )
*a7 = v13;
mylog("szConnStrOut = '%s'\n", a5);
qlog("conn=%u, SQLDriverConnect(out)='%s'\n", a1, a5);
mylog("SQLDRiverConnect: returning %d\n", (unsigned int)(__int16)v11);
}
else
{
CC_log_error("SQLDriverConnect", "Error from CC_Connect", a1);
v11 = -1;
}
}
}
else
{
CC_log_error("SQLDriverConnect", &LC5, 0LL);
v11 = -2;
}
return v11;
}

original_code:
RETCODE SQLDriverConnect(
            HDBC hdbc,
            HWND hwnd,
            UCHAR* szConnStrIn,
            SWORD cbConnStrIn,
            UCHAR* szConnStrOut,
            SWORD cbConnStrOutMax,
            SWORD* pcbConnStrOut,
            UWORD fDriverCompletion)
{
 dbc_t* pdbc = hdbc;
 char *dsn, *server;
 char buf[64];
 int sqlstat = en_00000;
 nnodbc_errstkunset(pdbc->herr);
 server = getkeyvalinstr((char*)szConnStrIn, cbConnStrIn,
         "Server", buf, sizeof(buf));
 if ( ! server )
 {
  dsn = getkeyvalinstr((char*)szConnStrIn, cbConnStrIn,
         "DSN", buf, sizeof(buf));
  if ( !dsn )
   dsn = "default";
  server = getkeyvalbydsn((char*)dsn, (-3), "Server",
          buf, sizeof(buf));
 }
 if ( ! server )
  buf[0] = 0;
 switch ( fDriverCompletion )
 {
 case 0:
  break;
 case 1:
 case 3:
  if ( ! server )
   break;
 case 2:
  if ( nnodbc_conndialog( hwnd, buf, sizeof(buf)) )
  {
   sqlstat = en_IM008;
   break;
  }
  server = buf;
  break;
 default:
  sqlstat = en_S1110;
  break;
 }
 if ( sqlstat != en_00000 )
 {
  pdbc->herr = nnodbc_pusherr(pdbc->herr, sqlstat, 0);
  return (-1);
 }
 if ( !server )
 {
  pdbc->herr = nnodbc_pusherr(pdbc->herr, en_S1000, "[NetNews ODBC][NNODBC driver]" "server name or address not specified");
  return (-1);
 }
 pdbc->hcndes = nntp_connect(server);
 if ( ! pdbc->hcndes )
 {
  pdbc->herr = nnodbc_pusherr(pdbc->herr, en_08001, 0);
  pdbc->herr = nnodbc_pusherr(pdbc->herr, (*__errno_location ()), nntp_errmsg(0));
  return (-1);
 }
 return 0;
}

canonical_original_code:
short SQLDriverConnect(void *hdbc, void *hwnd, unsigned char *szConnStrIn, short cbConnStrIn, unsigned char *szConnStrOut, short cbConnStrOutMax, short *pcbConnStrOut, unsigned short fDriverCompletion)
{
 struct DBC *pdbc = hdbc;
 char *dsn; char *server;
 char buf[64];
 int sqlstat = en_00000;
 nnodbc_errstkunset(pdbc->herr);
 server = getkeyvalinstr((char *)szConnStrIn, cbConnStrIn,
         "Server", buf, sizeof(buf));
 if ( ! server )
 {
  dsn = getkeyvalinstr((char *)szConnStrIn, cbConnStrIn,
         "DSN", buf, sizeof(buf));
  if ( !dsn )
   dsn = "default";
  server = getkeyvalbydsn((char *)dsn, (-3), "Server",
          buf, sizeof(buf));
 }
 if ( ! server )
  buf[0] = 0;
 switch ( fDriverCompletion )
 {
 case 0:
  break;
 case 1:
 case 3:
  if ( ! server )
   break;
 case 2:
  if ( nnodbc_conndialog( hwnd, buf, sizeof(buf)) )
  {
   sqlstat = en_IM008;
   break;
  }
  server = buf;
  break;
 default:
  sqlstat = en_S1110;
  break;
 }
 if ( sqlstat != en_00000 )
 {
  pdbc->herr = nnodbc_pusherr(pdbc->herr, sqlstat, 0);
  return (-1);
 }
 if ( !server )
 {
  pdbc->herr = nnodbc_pusherr(pdbc->herr, en_S1000, "[NetNews ODBC][NNODBC driver]" "server name or address not specified");
  return (-1);
 }
 pdbc->hcndes = nntp_connect(server);
 if ( ! pdbc->hcndes )
 {
  pdbc->herr = nnodbc_pusherr(pdbc->herr, en_08001, 0);
  pdbc->herr = nnodbc_pusherr(pdbc->herr, (*__errno_location ()), nntp_errmsg(0));
  return (-1);
 }
 return 0;
}

variable_types:
hdbc
void *

variable_types:
hwnd
void *

variable_types:
szConnStrIn
unsigned char *

variable_types: cbConnStrIn short

variable_types:
szConnStrOut
unsigned char *

variable_types: cbConnStrOutMax short

variable_types:
pcbConnStrOut
short *

variable_types:
fDriverCompletion
unsigned short

variable_types: struct DBC { void *hcndes; void *henv; struct GSTMT { void *hdbc; void *hstmt; struct GSTMT *next; } *stmt; void *herr; struct DBC *next; } *

variable_types:
dsn
char *

variable_types:
server
char *

variable_types:
buf
char [64]

variable_types: sqlstat int

return_type: short

user_defined_types: struct DBC { void *hcndes; void *henv; struct GSTMT *stmt; void *herr; struct DBC *next; }


SQLRemoveDSNFromIniW

decompiled_code:
__int64 __fastcall SQLRemoveDSNFromIniW(__int64 a1)
{
_BYTE *v1; // rbx
unsigned int v2; // ebp

inst_logClear();
v1 = (_BYTE *)single_string_alloc_and_copy(a1);
v2 = SQLRemoveDSNFromIni(v1);
free(v1);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
_BYTE *v1; // rbx
unsigned int v2; // ebp

inst_logClear();
v1 = (_BYTE *)single_string_alloc_and_copy(a1);
v2 = func0(v1);
free(v1);
return v2;
}

original_code:
int SQLRemoveDSNFromIniW(LPCWSTR lpszDSN)
{
 char *dsn;
 int ret;
    inst_logClear();
 dsn = _single_string_alloc_and_copy( lpszDSN );
 ret = SQLRemoveDSNFromIni( dsn );
 free( dsn );
 return ret;
}

canonical_original_code:
int SQLRemoveDSNFromIniW(unsigned short *lpszDSN)
{
 char *dsn;
 int ret;
    inst_logClear();
 dsn = _single_string_alloc_and_copy( lpszDSN );
 ret = SQLRemoveDSNFromIni( dsn );
 free( dsn );
 return ret;
}

variable_types:
lpszDSN
unsigned short *

variable_types: ret int

return_type: int


SQLStatistics

decompiled_code:
__int64 __fastcall SQLStatistics(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, _BYTE *a6)
{
void *v8; // rdi
__int64 result; // rax

if ( !a1 )
return 4294967294LL;
sprintf((char *)(a1 + 136), "hStmt = $%08lX", a1);
logPushMsg(*(_QWORD *)(a1 + 1160), "SQLStatistics.c", "SQLStatistics.c", 67LL, 1LL, 1LL, a1 + 136);
if ( a6 )
{
if ( *a6 )
{
if ( **(_QWORD **)(a1 + 1168) )
FreeResults();
v8 = *(void **)(a1 + 128);
if ( v8 )
free(v8);
*(_QWORD *)(a1 + 128) = 0LL;
logPushMsg(*(_QWORD *)(a1 + 1160), "SQLStatistics.c", "SQLStatistics.c", 111LL, 0LL, 0LL, "SQL_SUCCESS");
result = 0LL;
}
else
{
logPushMsg(
*(_QWORD *)(a1 + 1160),
"SQLStatistics.c",
"SQLStatistics.c",
77LL,
1LL,
1LL,
"SQL_ERROR No table name");
result = 0xFFFFFFFFLL;
}
}
else
{
logPushMsg(*(_QWORD *)(a1 + 1160), "SQLStatistics.c", "SQLStatistics.c", 71LL, 1LL, 1LL, "SQL_ERROR No table name");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, _BYTE *a6)
{
void *v8; // rdi
__int64 result; // rax

if ( !a1 )
return 4294967294LL;
sprintf((char *)(a1 + 136), "hStmt = $%08lX", a1);
logPushMsg(*(_QWORD *)(a1 + 1160), "SQLStatistics.c", "SQLStatistics.c", 67LL, 1LL, 1LL, a1 + 136);
if ( a6 )
{
if ( *a6 )
{
if ( **(_QWORD **)(a1 + 1168) )
FreeResults();
v8 = *(void **)(a1 + 128);
if ( v8 )
free(v8);
*(_QWORD *)(a1 + 128) = 0LL;
logPushMsg(*(_QWORD *)(a1 + 1160), "SQLStatistics.c", "SQLStatistics.c", 111LL, 0LL, 0LL, "SQL_SUCCESS");
result = 0LL;
}
else
{
logPushMsg(
*(_QWORD *)(a1 + 1160),
"SQLStatistics.c",
"SQLStatistics.c",
77LL,
1LL,
1LL,
"SQL_ERROR No table name");
result = 0xFFFFFFFFLL;
}
}
else
{
logPushMsg(*(_QWORD *)(a1 + 1160), "SQLStatistics.c", "SQLStatistics.c", 71LL, 1LL, 1LL, "SQL_ERROR No table name");
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
RETCODE SQLStatistics(
                              HSTMT hstmt,
                              UCHAR * szTableQualifier,
                              SWORD cbTableQualifier,
                              UCHAR * szTableOwner,
                              SWORD cbTableOwner,
                              UCHAR * szTableName,
                              SWORD cbTableName,
                              UWORD fUnique,
                              UWORD fAccuracy)
{
static char* const func="SQLStatistics";
StatementClass *stmt = (StatementClass *) hstmt;
char index_query[65536];
HSTMT hindx_stmt;
RETCODE result;
char *table_name;
char index_name[128];
short fields_vector[8];
char isunique[10], isclustered[10];
SDWORD index_name_len, fields_vector_len;
TupleNode *row;
int i;
HSTMT hcol_stmt;
StatementClass *col_stmt, *indx_stmt;
char column_name[128], relhasrules[128];
char **column_names = 0;
int column_name_len;
int total_columns = 0;
char error = (int)1;
ConnInfo *ci;
char buf[256];
mylog("%s: entering...stmt=%u\n", func, stmt);
    if( ! stmt) {
  SC_log_error(func, "", ((void *)0));
        return (-2);
    }
 stmt->manual_result = (int)1;
 stmt->errormsg_created = (int)1;
 ci = &stmt->hdbc->connInfo;
    stmt->result = QR_Constructor();
    if(!stmt->result) {
 SC_set_error(stmt, 4, "Couldn't allocate memory for SQLStatistics result.");
 SC_log_error(func, "", stmt);
 return (-1);
    }
    extend_bindings(stmt, 13);
    QR_set_num_fields(stmt->result, 13);
    (CI_set_field_info(stmt->result->fields, 0, "TABLE_QUALIFIER", 25, 128, -1));
    (CI_set_field_info(stmt->result->fields, 1, "TABLE_OWNER", 25, 128, -1));
    (CI_set_field_info(stmt->result->fields, 2, "TABLE_NAME", 25, 128, -1));
    (CI_set_field_info(stmt->result->fields, 3, "NON_UNIQUE", 21, 2, -1));
    (CI_set_field_info(stmt->result->fields, 4, "INDEX_QUALIFIER", 25, 128, -1));
    (CI_set_field_info(stmt->result->fields, 5, "INDEX_NAME", 25, 128, -1));
    (CI_set_field_info(stmt->result->fields, 6, "TYPE", 21, 2, -1));
    (CI_set_field_info(stmt->result->fields, 7, "SEQ_IN_INDEX", 21, 2, -1));
    (CI_set_field_info(stmt->result->fields, 8, "COLUMN_NAME", 25, 128, -1));
    (CI_set_field_info(stmt->result->fields, 9, "COLLATION", 18, 1, -1));
    (CI_set_field_info(stmt->result->fields, 10, "CARDINALITY", 23, 4, -1));
    (CI_set_field_info(stmt->result->fields, 11, "PAGES", 23, 4, -1));
    (CI_set_field_info(stmt->result->fields, 12, "FILTER_CONDITION", 25, 128, -1));
 table_name = make_string((char*)szTableName, cbTableName, ((void *)0));
 if ( ! table_name) {
  SC_set_error(stmt, 8, "No table name passed to SQLStatistics.");
  SC_log_error(func, "", stmt);
  return (-1);
 }
 result = PG_SQLAllocStmt( stmt->hdbc, &hcol_stmt);
 if((result != 0) && (result != 1)) {
  SC_set_error(stmt, 4, "SQLAllocStmt failed in SQLStatistics for columns.");
  goto SEEYA;
 }
 col_stmt = (StatementClass *) hcol_stmt;
 col_stmt->internal = (int)1;
 result = PG_SQLColumns(hcol_stmt, (SQLCHAR*)"", 0, (SQLCHAR*)"", 0,
    (SQLCHAR*)table_name, (SWORD) strlen(table_name), (SQLCHAR*)"", 0);
 col_stmt->internal = (int)0;
 if((result != 0) && (result != 1)) {
   SC_set_error(stmt, (col_stmt->__error_number), (col_stmt->__error_message));
   PG_SQLFreeStmt(hcol_stmt, 1);
   goto SEEYA;
 }
 result = PG_SQLBindCol(hcol_stmt, 4, 1,
    column_name, 128, &column_name_len);
 if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (col_stmt->__error_number), (col_stmt->__error_message));
  PG_SQLFreeStmt(hcol_stmt, 1);
  goto SEEYA;
 }
 result = PG_SQLFetch(hcol_stmt);
 while((result == 0) || (result == 1)) {
  total_columns++;
  column_names =
  (char **)realloc(column_names,
     total_columns * sizeof(char *));
  column_names[total_columns-1] =
  (char *)malloc(strlen(column_name)+1);
  strcpy(column_names[total_columns-1], column_name);
  mylog("SQLStatistics: column_name = '%s'\n", column_name);
  result = PG_SQLFetch(hcol_stmt);
 }
 if(result != 100 || total_columns == 0) {
   SC_set_error(stmt, (col_stmt->__error_number), SC_create_errormsg((StatementClass *)hcol_stmt));
   PG_SQLFreeStmt(hcol_stmt, 1);
      goto SEEYA;
 }
 PG_SQLFreeStmt(hcol_stmt, 1);
    result = PG_SQLAllocStmt( stmt->hdbc, &hindx_stmt);
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, 4, "SQLAllocStmt failed in SQLStatistics for indices.");
  goto SEEYA;
    }
 indx_stmt = (StatementClass *) hindx_stmt;
 sprintf(index_query, "select c.relname, i.indkey, i.indisunique"
   ", i.indisclustered, c.relhasrules"
   " from pg_index i, pg_class c, pg_class d"
   " where c.oid = i.indexrelid and d.relname = '%s'"
   " and d.oid = i.indrelid", table_name);
    result = PG_SQLExecDirect(hindx_stmt, index_query, strlen(index_query));
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (indx_stmt->__error_number), SC_create_errormsg((StatementClass *)hindx_stmt));
  PG_SQLFreeStmt(hindx_stmt, 1);
    goto SEEYA;
    }
    result = PG_SQLBindCol(hindx_stmt, 1, 1,
                        index_name, 128, &index_name_len);
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (indx_stmt->__error_number), (indx_stmt->__error_message));
  PG_SQLFreeStmt(hindx_stmt, 1);
     goto SEEYA;
    }
    result = PG_SQLBindCol(hindx_stmt, 2, 99,
                        fields_vector, 16, &fields_vector_len);
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (indx_stmt->__error_number), (indx_stmt->__error_message));
  PG_SQLFreeStmt(hindx_stmt, 1);
  goto SEEYA;
    }
    result = PG_SQLBindCol(hindx_stmt, 3, 1,
                        isunique, sizeof(isunique), ((void *)0));
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (indx_stmt->__error_number), (indx_stmt->__error_message));
  PG_SQLFreeStmt(hindx_stmt, 1);
  goto SEEYA;
    }
    result = PG_SQLBindCol(hindx_stmt, 4, 1,
                        isclustered, sizeof(isclustered), ((void *)0));
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (indx_stmt->__error_number), (indx_stmt->__error_message));
  PG_SQLFreeStmt(hindx_stmt, 1);
  goto SEEYA;
    }
    result = PG_SQLBindCol(hindx_stmt, 5, 1,
                        relhasrules, 128, ((void *)0));
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (indx_stmt->__error_number), (indx_stmt->__error_message));
  PG_SQLFreeStmt(hindx_stmt, 1);
        goto SEEYA;
    }
 if ( relhasrules[0] != '1' && atoi(ci->show_oid_column) && atoi(ci->fake_oid_index)) {
  row = (TupleNode *)malloc(sizeof(TupleNode) +
       (13 - 1) * sizeof(TupleField));
  set_tuplefield_string(&row->tuple[0], "");
  set_tuplefield_string(&row->tuple[1], "");
  set_tuplefield_string(&row->tuple[2], table_name);
  set_tuplefield_int2(&row->tuple[3], (short) (globals.unique_index ? (int)0 : (int)1));
  set_tuplefield_string(&row->tuple[4], "");
  sprintf(buf, "%s_idx_fake_oid", table_name);
  set_tuplefield_string(&row->tuple[5], buf);
  set_tuplefield_int2(&row->tuple[6], (short) 3);
  set_tuplefield_int2(&row->tuple[7], (short) 1);
  set_tuplefield_string(&row->tuple[8], "oid");
  set_tuplefield_string(&row->tuple[9], "A");
  set_tuplefield_null(&row->tuple[10]);
  set_tuplefield_null(&row->tuple[11]);
  set_tuplefield_null(&row->tuple[12]);
  (TL_add_tuple(stmt->result->manual_tuples, row));
 }
    result = PG_SQLFetch(hindx_stmt);
    while((result == 0) || (result == 1)) {
  if (fUnique == 1 ||
   (fUnique == 0 && atoi(isunique))) {
   i = 0;
   while(i < 8 && fields_vector[i] != 0) {
    row = (TupleNode *)malloc(sizeof(TupleNode) +
         (13 - 1) * sizeof(TupleField));
    set_tuplefield_string(&row->tuple[0], "");
    set_tuplefield_string(&row->tuple[1], "");
    set_tuplefield_string(&row->tuple[2], table_name);
    if (globals.unique_index)
     set_tuplefield_int2(&row->tuple[3], (short) (atoi(isunique) ? (int)0 : (int)1));
    else
     set_tuplefield_int2(&row->tuple[3], (int)1);
    set_tuplefield_string(&row->tuple[4], "");
    set_tuplefield_string(&row->tuple[5], index_name);
    set_tuplefield_int2(&row->tuple[6], (short) (atoi(isclustered) ? 1 : 3));
    set_tuplefield_int2(&row->tuple[7], (short) (i+1));
    if(fields_vector[i] == -2) {
     set_tuplefield_string(&row->tuple[8], "oid");
     mylog("SQLStatistics: column name = oid\n");
    }
    else if(fields_vector[i] < 0 || fields_vector[i] > total_columns) {
     set_tuplefield_string(&row->tuple[8], "UNKNOWN");
     mylog("SQLStatistics: column name = UNKNOWN\n");
    }
    else {
     set_tuplefield_string(&row->tuple[8], column_names[fields_vector[i]-1]);
     mylog("SQLStatistics: column name = '%s'\n", column_names[fields_vector[i]-1]);
    }
    set_tuplefield_string(&row->tuple[9], "A");
    set_tuplefield_null(&row->tuple[10]);
    set_tuplefield_null(&row->tuple[11]);
    set_tuplefield_null(&row->tuple[12]);
    (TL_add_tuple(stmt->result->manual_tuples, row));
    i++;
   }
  }
        result = PG_SQLFetch(hindx_stmt);
    }
    if(result != 100) {
  SC_set_error(stmt, (indx_stmt->__error_number), SC_create_errormsg((StatementClass *)hindx_stmt));
  PG_SQLFreeStmt(hindx_stmt, 1);
  goto SEEYA;
    }
 PG_SQLFreeStmt(hindx_stmt, 1);
    stmt->status = STMT_FINISHED;
    stmt->currTuple = -1;
 stmt->rowset_start = -1;
 stmt->current_col = -1;
 error = (int)0;
SEEYA:
 free(table_name);
    for(i = 0; i < total_columns; i++) {
  free(column_names[i]);
    }
    free(column_names);
 mylog("SQLStatistics(): EXIT, %s, stmt=%u\n", error ? "error" : "success", stmt);
 if (error) {
  SC_log_error(func, "", stmt);
  return (-1);
 }
 else
  return 0;
}

canonical_original_code:
short SQLStatistics(void *hstmt, unsigned char *szTableQualifier, short cbTableQualifier, unsigned char *szTableOwner, short cbTableOwner, unsigned char *szTableName, short cbTableName, unsigned short fUnique, unsigned short fAccuracy)
{
static char *func = "SQLStatistics";
struct StatementClass_ *stmt = (StatementClass *) hstmt;
char index_query[65536];
void *hindx_stmt;
short result;
char *table_name;
char index_name[128];
short fields_vector[8];
char isunique[10]; char isclustered[10];
long index_name_len; long fields_vector_len;
struct TupleNode_ *row;
int i;
void *hcol_stmt;
struct StatementClass_ *col_stmt; struct StatementClass_ *indx_stmt;
char column_name[128]; char relhasrules[128];
char **column_names = 0;
int column_name_len;
int total_columns = 0;
char error = (int)1;
struct ConnInfo *ci;
char buf[256];
mylog("%s: entering...stmt=%u\n", func, stmt);
    if( ! stmt) {
  SC_log_error(func, "", ((void *)0));
        return (-2);
    }
 stmt->manual_result = (int)1;
 stmt->errormsg_created = (int)1;
 ci = &stmt->hdbc->connInfo;
    stmt->result = QR_Constructor();
    if(!stmt->result) {
 SC_set_error(stmt, 4, "Couldn't allocate memory for SQLStatistics result.");
 SC_log_error(func, "", stmt);
 return (-1);
    }
    extend_bindings(stmt, 13);
    QR_set_num_fields(stmt->result, 13);
    (CI_set_field_info(stmt->result->fields, 0, "TABLE_QUALIFIER", 25, 128, -1));
    (CI_set_field_info(stmt->result->fields, 1, "TABLE_OWNER", 25, 128, -1));
    (CI_set_field_info(stmt->result->fields, 2, "TABLE_NAME", 25, 128, -1));
    (CI_set_field_info(stmt->result->fields, 3, "NON_UNIQUE", 21, 2, -1));
    (CI_set_field_info(stmt->result->fields, 4, "INDEX_QUALIFIER", 25, 128, -1));
    (CI_set_field_info(stmt->result->fields, 5, "INDEX_NAME", 25, 128, -1));
    (CI_set_field_info(stmt->result->fields, 6, "TYPE", 21, 2, -1));
    (CI_set_field_info(stmt->result->fields, 7, "SEQ_IN_INDEX", 21, 2, -1));
    (CI_set_field_info(stmt->result->fields, 8, "COLUMN_NAME", 25, 128, -1));
    (CI_set_field_info(stmt->result->fields, 9, "COLLATION", 18, 1, -1));
    (CI_set_field_info(stmt->result->fields, 10, "CARDINALITY", 23, 4, -1));
    (CI_set_field_info(stmt->result->fields, 11, "PAGES", 23, 4, -1));
    (CI_set_field_info(stmt->result->fields, 12, "FILTER_CONDITION", 25, 128, -1));
 table_name = make_string((char *)szTableName, cbTableName, ((void *)0));
 if ( ! table_name) {
  SC_set_error(stmt, 8, "No table name passed to SQLStatistics.");
  SC_log_error(func, "", stmt);
  return (-1);
 }
 result = PG_SQLAllocStmt( stmt->hdbc, &hcol_stmt);
 if((result != 0) && (result != 1)) {
  SC_set_error(stmt, 4, "SQLAllocStmt failed in SQLStatistics for columns.");
  goto SEEYA;
 }
 col_stmt = (struct StatementClass_ *) hcol_stmt;
 col_stmt->internal = (int)1;
 result = PG_SQLColumns(hcol_stmt, (unsigned char *)"", 0, (unsigned char *)"", 0,
    (unsigned char *)table_name, (short) strlen(table_name), (unsigned char *)"", 0);
 col_stmt->internal = (int)0;
 if((result != 0) && (result != 1)) {
   SC_set_error(stmt, (col_stmt->__error_number), (col_stmt->__error_message));
   PG_SQLFreeStmt(hcol_stmt, 1);
   goto SEEYA;
 }
 result = PG_SQLBindCol(hcol_stmt, 4, 1,
    column_name, 128, &column_name_len);
 if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (col_stmt->__error_number), (col_stmt->__error_message));
  PG_SQLFreeStmt(hcol_stmt, 1);
  goto SEEYA;
 }
 result = PG_SQLFetch(hcol_stmt);
 while((result == 0) || (result == 1)) {
  total_columns++;
  column_names =
  (char **)realloc(column_names,
     total_columns * sizeof(char *));
  column_names[total_columns-1] =
  (char *)malloc(strlen(column_name)+1);
  strcpy(column_names[total_columns-1], column_name);
  mylog("SQLStatistics: column_name = '%s'\n", column_name);
  result = PG_SQLFetch(hcol_stmt);
 }
 if(result != 100 || total_columns == 0) {
   SC_set_error(stmt, (col_stmt->__error_number), SC_create_errormsg((struct StatementClass_ *)hcol_stmt));
   PG_SQLFreeStmt(hcol_stmt, 1);
      goto SEEYA;
 }
 PG_SQLFreeStmt(hcol_stmt, 1);
    result = PG_SQLAllocStmt( stmt->hdbc, &hindx_stmt);
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, 4, "SQLAllocStmt failed in SQLStatistics for indices.");
  goto SEEYA;
    }
 indx_stmt = (struct StatementClass_ *) hindx_stmt;
 sprintf(index_query, "select c.relname, i.indkey, i.indisunique"
   ", i.indisclustered, c.relhasrules"
   " from pg_index i, pg_class c, pg_class d"
   " where c.oid = i.indexrelid and d.relname = '%s'"
   " and d.oid = i.indrelid", table_name);
    result = PG_SQLExecDirect(hindx_stmt, index_query, strlen(index_query));
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (indx_stmt->__error_number), SC_create_errormsg((struct StatementClass_ *)hindx_stmt));
  PG_SQLFreeStmt(hindx_stmt, 1);
    goto SEEYA;
    }
    result = PG_SQLBindCol(hindx_stmt, 1, 1,
                        index_name, 128, &index_name_len);
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (indx_stmt->__error_number), (indx_stmt->__error_message));
  PG_SQLFreeStmt(hindx_stmt, 1);
     goto SEEYA;
    }
    result = PG_SQLBindCol(hindx_stmt, 2, 99,
                        fields_vector, 16, &fields_vector_len);
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (indx_stmt->__error_number), (indx_stmt->__error_message));
  PG_SQLFreeStmt(hindx_stmt, 1);
  goto SEEYA;
    }
    result = PG_SQLBindCol(hindx_stmt, 3, 1,
                        isunique, sizeof(isunique), ((void *)0));
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (indx_stmt->__error_number), (indx_stmt->__error_message));
  PG_SQLFreeStmt(hindx_stmt, 1);
  goto SEEYA;
    }
    result = PG_SQLBindCol(hindx_stmt, 4, 1,
                        isclustered, sizeof(isclustered), ((void *)0));
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (indx_stmt->__error_number), (indx_stmt->__error_message));
  PG_SQLFreeStmt(hindx_stmt, 1);
  goto SEEYA;
    }
    result = PG_SQLBindCol(hindx_stmt, 5, 1,
                        relhasrules, 128, ((void *)0));
    if((result != 0) && (result != 1)) {
  SC_set_error(stmt, (indx_stmt->__error_number), (indx_stmt->__error_message));
  PG_SQLFreeStmt(hindx_stmt, 1);
        goto SEEYA;
    }
 if ( relhasrules[0] != '1' && atoi(ci->show_oid_column) && atoi(ci->fake_oid_index)) {
  row = (struct TupleNode_ *)malloc(sizeof(TupleNode) +
       (13 - 1) * sizeof(TupleField));
  set_tuplefield_string(&row->tuple[0], "");
  set_tuplefield_string(&row->tuple[1], "");
  set_tuplefield_string(&row->tuple[2], table_name);
  set_tuplefield_int2(&row->tuple[3], (short) (globals.unique_index ? (int)0 : (int)1));
  set_tuplefield_string(&row->tuple[4], "");
  sprintf(buf, "%s_idx_fake_oid", table_name);
  set_tuplefield_string(&row->tuple[5], buf);
  set_tuplefield_int2(&row->tuple[6], (short) 3);
  set_tuplefield_int2(&row->tuple[7], (short) 1);
  set_tuplefield_string(&row->tuple[8], "oid");
  set_tuplefield_string(&row->tuple[9], "A");
  set_tuplefield_null(&row->tuple[10]);
  set_tuplefield_null(&row->tuple[11]);
  set_tuplefield_null(&row->tuple[12]);
  (TL_add_tuple(stmt->result->manual_tuples, row));
 }
    result = PG_SQLFetch(hindx_stmt);
    while((result == 0) || (result == 1)) {
  if (fUnique == 1 ||
   (fUnique == 0 && atoi(isunique))) {
   i = 0;
   while(i < 8 && fields_vector[i] != 0) {
    row = (struct TupleNode_ *)malloc(sizeof(TupleNode) +
         (13 - 1) * sizeof(TupleField));
    set_tuplefield_string(&row->tuple[0], "");
    set_tuplefield_string(&row->tuple[1], "");
    set_tuplefield_string(&row->tuple[2], table_name);
    if (globals.unique_index)
     set_tuplefield_int2(&row->tuple[3], (short) (atoi(isunique) ? (int)0 : (int)1));
    else
     set_tuplefield_int2(&row->tuple[3], (int)1);
    set_tuplefield_string(&row->tuple[4], "");
    set_tuplefield_string(&row->tuple[5], index_name);
    set_tuplefield_int2(&row->tuple[6], (short) (atoi(isclustered) ? 1 : 3));
    set_tuplefield_int2(&row->tuple[7], (short) (i+1));
    if(fields_vector[i] == -2) {
     set_tuplefield_string(&row->tuple[8], "oid");
     mylog("SQLStatistics: column name = oid\n");
    }
    else if(fields_vector[i] < 0 || fields_vector[i] > total_columns) {
     set_tuplefield_string(&row->tuple[8], "UNKNOWN");
     mylog("SQLStatistics: column name = UNKNOWN\n");
    }
    else {
     set_tuplefield_string(&row->tuple[8], column_names[fields_vector[i]-1]);
     mylog("SQLStatistics: column name = '%s'\n", column_names[fields_vector[i]-1]);
    }
    set_tuplefield_string(&row->tuple[9], "A");
    set_tuplefield_null(&row->tuple[10]);
    set_tuplefield_null(&row->tuple[11]);
    set_tuplefield_null(&row->tuple[12]);
    (TL_add_tuple(stmt->result->manual_tuples, row));
    i++;
   }
  }
        result = PG_SQLFetch(hindx_stmt);
    }
    if(result != 100) {
  SC_set_error(stmt, (indx_stmt->__error_number), SC_create_errormsg((struct StatementClass_ *)hindx_stmt));
  PG_SQLFreeStmt(hindx_stmt, 1);
  goto SEEYA;
    }
 PG_SQLFreeStmt(hindx_stmt, 1);
    stmt->status = STMT_FINISHED;
    stmt->currTuple = -1;
 stmt->rowset_start = -1;
 stmt->current_col = -1;
 error = (int)0;
SEEYA:
 free(table_name);
    for(i = 0; i < total_columns; i++) {
  free(column_names[i]);
    }
    free(column_names);
 mylog("SQLStatistics(): EXIT, %s, stmt=%u\n", error ? "error" : "success", stmt);
 if (error) {
  SC_log_error(func, "", stmt);
  return (-1);
 }
 else
  return 0;
}

variable_types:
hstmt
void *

variable_types:
szTableQualifier
unsigned char *

variable_types: cbTableQualifier short

variable_types:
szTableOwner
unsigned char *

variable_types: cbTableOwner short

variable_types:
szTableName
unsigned char *

variable_types: cbTableName short

variable_types:
fUnique
unsigned short

variable_types:
fAccuracy
unsigned short

variable_types:
func
char *

variable_types: struct StatementClass_ { struct ConnectionClass_ { void *henv; struct StatementOptions_ { int maxRows; int maxLength; int rowset_size; int keyset_size; int cursor_type; int scroll_concurrency; int retrieve_data; int bind_size; int use_bookmarks; } stmtOptions; char *__error_message; int __error_number; enum CONN_Status { CONN_NOT_CONNECTED=0, CONN_CONNECTED=1, CONN_DOWN=2, CONN_EXECUTING=3 } status; struct ConnInfo { char dsn[256]; char desc[256]; char driver[256]; char server[256]; char database[256]; char username[256]; char password[256]; char conn_settings[4096]; char protocol[10]; char port[10]; char uds[4096]; char onlyread[10]; char fake_oid_index[10]; char show_oid_column[10]; char row_versioning[10]; char show_system_tables[10]; char translation_dll[256]; char translation_option[10]; char focus_password; } connInfo; struct StatementClass_ **stmts; int num_stmts; struct SocketClass_ { int buffer_filled_in; int buffer_filled_out; int buffer_read_in; unsigned char *buffer_in; unsigned char *buffer_out; int socket; char *errormsg; int errornumber; char reverse; } *sock; int lobj_type; int ntables; struct col_info { struct QResultClass_ { struct ColumnInfoClass_ { short num_fields; char **name; unsigned int *adtid; short *adtsize; short *display_size; int *atttypmod; } *fields; struct TupleListClass_ { int num_fields; int num_tuples; struct TupleNode_ { struct TupleNode_ *prev; struct TupleField_ { int len; void *value; } tuple[1]; } *list_start; int last_indexed; } *manual_tuples; struct ConnectionClass_ *conn; int fetch_count; int fcount; int currTuple; int base; int num_fields; int cache_size; int rowset_size; enum QueryResultCode_ { PGRES_EMPTY_QUERY=0, PGRES_COMMAND_OK=1, PGRES_TUPLES_OK=2, PGRES_COPY_OUT=3, PGRES_COPY_IN=4, PGRES_BAD_RESPONSE=5, PGRES_NONFATAL_ERROR=6, PGRES_FATAL_ERROR=7, PGRES_FIELDS_OK=8, PGRES_END_TUPLES=9, PGRES_INTERNAL_ERROR=10 } status; char *message; char *cursor; char *command; char *notice; struct TupleField_ *backend_tuples; struct TupleField_ *tupleField; char inTuples; char aborted; } *result; char name[-1]; } **col_info; long translation_option; void *translation_handle; int (*DataSourceToDriver)(unsigned long, short, void *, long, void *, long, long *, unsigned char *, short, short *); int (*DriverToDataSource)(unsigned long, short, void *, long, void *, long, long *, unsigned char *, short, short *); short driver_version; char transact_status; char errormsg_created; char pg_version[128]; float pg_version_number; short pg_version_major; short pg_version_minor; char ms_jet; char unicode; char result_uncommitted; char schema_support; char *client_encoding; char *server_encoding; int ccsc; int be_pid; int be_key; unsigned int isolation; char *current_schema; int num_discardp; char **discardp; } *hdbc; struct QResultClass_ *result; void **phstmt; struct StatementOptions_ options; enum STMT_Status { STMT_ALLOCATED=0, STMT_READY=1, STMT_PREMATURE=2, STMT_FINISHED=3, STMT_EXECUTING=4 } status; char *__error_message; int __error_number; struct BindInfoClass_ { int buflen; int data_left; char *buffer; long *used; short returntype; } *bindings; struct BindInfoClass_ bookmark; int bindings_allocated; int parameters_allocated; struct ParameterInfoClass_ { int buflen; char *buffer; long *used; short paramType; short CType; short SQLType; unsigned int precision; short scale; unsigned int lobj_oid; int *EXEC_used; char *EXEC_buffer; char data_at_exec; } *parameters; int currTuple; int save_rowset_size; int rowset_start; int bind_row; int last_fetch_count; int current_col; int lobj_fd; char *statement; struct TABLE_INFO { struct col_info *col_info; char name[-1]; char alias[-1]; } **ti; struct FIELD_INFO { struct TABLE_INFO *ti; int precision; int display_size; int length; int type; char nullable; char func; char expr; char quote; char dquote; char numeric; char dot[-1]; char name[-1]; char alias[-1]; } **fi; int nfld; int ntab; int parse_status; int statement_type; int data_at_exec; int current_exec_param; char put_data; char errormsg_created; char manual_result; char prepare; char internal; char cursor_name[-1]; char stmt_with_params[65536]; int reexecute; } *

variable_types: result short

variable_types:
isunique
char [10]

variable_types:
isclustered
char [10]

variable_types: i int

variable_types:
relhasrules
char [128]

variable_types: error char

variable_types: struct ConnInfo { char dsn[256]; char desc[256]; char driver[256]; char server[256]; char database[256]; char username[256]; char password[256]; char conn_settings[4096]; char protocol[10]; char port[10]; char uds[4096]; char onlyread[10]; char fake_oid_index[10]; char show_oid_column[10]; char row_versioning[10]; char show_system_tables[10]; char translation_dll[256]; char translation_option[10]; char focus_password; } *

variable_types:
buf
char [256]

user_defined_types: struct StatementClass_ { struct ConnectionClass_ *hdbc; struct QResultClass_ *result; void **phstmt; struct StatementOptions_ options; enum STMT_Status status; char *__error_message; int __error_number; struct BindInfoClass_ *bindings; struct BindInfoClass_ bookmark; int bindings_allocated; int parameters_allocated; struct ParameterInfoClass_ *parameters; int currTuple; int save_rowset_size; int rowset_start; int bind_row; int last_fetch_count; int current_col; int lobj_fd; char *statement; struct TABLE_INFO **ti; struct FIELD_INFO **fi; int nfld; int ntab; int parse_status; int statement_type; int data_at_exec; int current_exec_param; char put_data; char errormsg_created; char manual_result; char prepare; char internal; char cursor_name[-1]; char stmt_with_params[65536]; int reexecute; }

user_defined_types: struct col_info { struct QResultClass_ *result; char name[-1]; }

user_defined_types: struct QResultClass_ { struct ColumnInfoClass_ *fields; struct TupleListClass_ *manual_tuples; struct ConnectionClass_ *conn; int fetch_count; int fcount; int currTuple; int base; int num_fields; int cache_size; int rowset_size; enum QueryResultCode_ status; char *message; char *cursor; char *command; char *notice; struct TupleField_ *backend_tuples; struct TupleField_ *tupleField; char inTuples; char aborted; }


SQLBulkOperations

decompiled_code:
__int64 __fastcall SQLBulkOperations(__int64 a1, __int16 a2)
{
int v2; // eax
__int64 v3; // rcx
__int64 v4; // rax
__int64 (__fastcall *v5)(_QWORD, _QWORD); // rdx
__int16 v6; // bp
__int64 (__fastcall *v8)(_QWORD, _QWORD, __int64, _QWORD); // r8
const char *v9; // rax
__int64 v10; // [rsp+0h] [rbp-108h] BYREF

if ( !(unsigned int)_validate_stmt() )
{
dm_log_write("SQLBulkOperations.c", 124LL, 0LL, 0LL, "Error: SQL_INVALID_HANDLE");
return 4294967294LL;
}
function_entry(a1);
if ( log_info[4] )
{
sprintf(
(char *)(a1 + 16),
"\n\t\tEntry:\n\t\t\tStatement = %p\n\t\t\tOption = %d",
(const void *)a1,
(unsigned int)a2);
dm_log_write("SQLBulkOperations.c", 143LL, 0LL, 0LL, a1 + 16);
}
thread_protect(3LL, a1);
v2 = *(_DWORD *)(a1 + 1040);
if ( (unsigned int)(v2 - 1) <= 2 )
{
dm_log_write("SQLBulkOperations.c", 160LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1088, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( v2 == 4 )
{
dm_log_write("SQLBulkOperations.c", 175LL, 0LL, 0LL, "Error: 24000");
_post_internal_error(a1 + 1088, 8LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( v2 == 7 )
{
dm_log_write("SQLBulkOperations.c", 190LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1088, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( (unsigned int)(v2 - 8) <= 2 )
{
dm_log_write("SQLBulkOperations.c", 207LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1088, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( (unsigned int)(v2 - 11) <= 1 && *(_DWORD *)(a1 + 1072) != 24 )
{
dm_log_write("SQLBulkOperations.c", 225LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1088, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
v3 = *(_QWORD *)(a1 + 1048);
v4 = *(_QWORD *)(v3 + 1320);
v5 = *(__int64 (__fastcall **)(_QWORD, _QWORD))(v4 + 608);
if ( v5 )
{
v6 = v5(*(_QWORD *)(a1 + 1056), (unsigned int)a2);
}
else
{
v8 = *(__int64 (__fastcall **)(_QWORD, _QWORD, __int64, _QWORD))(v4 + 4384);
if ( !v8 || *(_DWORD *)(v3 + 1484) != 2 || a2 != 4 )
{
dm_log_write("SQLBulkOperations.c", 261LL, 0LL, 0LL, "Error: IM001");
_post_internal_error(a1 + 1088, 42LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
v6 = v8(*(_QWORD *)(a1 + 1056), 0LL, 4LL, 0LL);
}
if ( v6 == 2 )
{
*(_DWORD *)(a1 + 1072) = 24;
if ( (unsigned int)(*(_DWORD *)(a1 + 1040) - 11) > 1 )
*(_DWORD *)(a1 + 1040) = 11;
}
else if ( v6 == 99 )
{
*(_DWORD *)(a1 + 1072) = 24;
*(_DWORD *)(a1 + 1076) = *(_DWORD *)(a1 + 1040);
*(_DWORD *)(a1 + 1040) = 8;
}
if ( log_info[4] )
{
v9 = (const char *)_get_return_status((unsigned int)v6, &v10);
sprintf((char *)(a1 + 16), "\n\t\tExit:[%s]", v9);
dm_log_write("SQLBulkOperations.c", 294LL, 0LL, 0LL, a1 + 16);
}
return function_return_ex(3LL, a1, (unsigned int)v6, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int16 a2)
{
int v2; // eax
__int64 v3; // rcx
__int64 v4; // rax
__int64 (__fastcall *v5)(_QWORD, _QWORD); // rdx
__int16 v6; // bp
__int64 (__fastcall *v8)(_QWORD, _QWORD, __int64, _QWORD); // r8
const char *v9; // rax
__int64 v10; // [rsp+0h] [rbp-108h] BYREF

if ( !(unsigned int)_validate_stmt() )
{
dm_log_write("SQLBulkOperations.c", 124LL, 0LL, 0LL, "Error: SQL_INVALID_HANDLE");
return 4294967294LL;
}
function_entry(a1);
if ( log_info[4] )
{
sprintf(
(char *)(a1 + 16),
"\n\t\tEntry:\n\t\t\tStatement = %p\n\t\t\tOption = %d",
(const void *)a1,
(unsigned int)a2);
dm_log_write("SQLBulkOperations.c", 143LL, 0LL, 0LL, a1 + 16);
}
thread_protect(3LL, a1);
v2 = *(_DWORD *)(a1 + 1040);
if ( (unsigned int)(v2 - 1) <= 2 )
{
dm_log_write("SQLBulkOperations.c", 160LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1088, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( v2 == 4 )
{
dm_log_write("SQLBulkOperations.c", 175LL, 0LL, 0LL, "Error: 24000");
_post_internal_error(a1 + 1088, 8LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( v2 == 7 )
{
dm_log_write("SQLBulkOperations.c", 190LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1088, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( (unsigned int)(v2 - 8) <= 2 )
{
dm_log_write("SQLBulkOperations.c", 207LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1088, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( (unsigned int)(v2 - 11) <= 1 && *(_DWORD *)(a1 + 1072) != 24 )
{
dm_log_write("SQLBulkOperations.c", 225LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1088, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
v3 = *(_QWORD *)(a1 + 1048);
v4 = *(_QWORD *)(v3 + 1320);
v5 = *(__int64 (__fastcall **)(_QWORD, _QWORD))(v4 + 608);
if ( v5 )
{
v6 = v5(*(_QWORD *)(a1 + 1056), (unsigned int)a2);
}
else
{
v8 = *(__int64 (__fastcall **)(_QWORD, _QWORD, __int64, _QWORD))(v4 + 4384);
if ( !v8 || *(_DWORD *)(v3 + 1484) != 2 || a2 != 4 )
{
dm_log_write("SQLBulkOperations.c", 261LL, 0LL, 0LL, "Error: IM001");
_post_internal_error(a1 + 1088, 42LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1048) + 1048LL) + 1048LL));
return function_return_ex(3LL, a1, 0xFFFFFFFFLL, 0LL);
}
v6 = v8(*(_QWORD *)(a1 + 1056), 0LL, 4LL, 0LL);
}
if ( v6 == 2 )
{
*(_DWORD *)(a1 + 1072) = 24;
if ( (unsigned int)(*(_DWORD *)(a1 + 1040) - 11) > 1 )
*(_DWORD *)(a1 + 1040) = 11;
}
else if ( v6 == 99 )
{
*(_DWORD *)(a1 + 1072) = 24;
*(_DWORD *)(a1 + 1076) = *(_DWORD *)(a1 + 1040);
*(_DWORD *)(a1 + 1040) = 8;
}
if ( log_info[4] )
{
v9 = (const char *)_get_return_status((unsigned int)v6, &v10);
sprintf((char *)(a1 + 16), "\n\t\tExit:[%s]", v9);
dm_log_write("SQLBulkOperations.c", 294LL, 0LL, 0LL, a1 + 16);
}
return function_return_ex(3LL, a1, (unsigned int)v6, 0LL);
}

original_code:
SQLRETURN SQLBulkOperations(
    SQLHSTMT statement_handle,
    SQLSMALLINT operation )
{
    DMHSTMT statement = (DMHSTMT)statement_handle;
    SQLRETURN ret;
    SQLCHAR s1[ 100 + 128 ];
    if ( !__validate_stmt( statement ))
    {
        dm_log_write( "SQLBulkOperations.c",
                124,
                    0,
                    0,
                    "Error: SQL_INVALID_HANDLE" );
        return (-2);
    }
    function_entry( statement );
    if ( log_info.log_flag )
    {
        sprintf( statement -> msg, "\n\t\tEntry:\n\t\t\tStatement = %p\n\t\t\tOption = %d",
                statement,
                operation );
        dm_log_write( "SQLBulkOperations.c",
                143,
                0,
                0,
                statement -> msg );
    }
    thread_protect( 3, statement );
    if ( statement -> state == 1 ||
            statement -> state == 2 ||
            statement -> state == 3 )
    {
        dm_log_write( "SQLBulkOperations.c",
                160,
                0,
                0,
                "Error: HY010" );
        __post_internal_error( &statement -> error,
                ERROR_HY010, ((void *)0),
                statement -> connection -> environment -> requested_version );
        return function_return_ex(3,statement,(-1),0);
    }
    if ( statement -> state == 4 )
    {
        dm_log_write( "SQLBulkOperations.c",
                175,
                0,
                0,
                "Error: 24000" );
        __post_internal_error( &statement -> error,
                ERROR_24000, ((void *)0),
                statement -> connection -> environment -> requested_version );
        return function_return_ex(3,statement,(-1),0);
    }
    if ( statement -> state == 7 )
    {
        dm_log_write( "SQLBulkOperations.c",
                190,
                0,
                0,
                "Error: HY010" );
        __post_internal_error( &statement -> error,
                ERROR_HY010, ((void *)0),
                statement -> connection -> environment -> requested_version );
        return function_return_ex(3,statement,(-1),0);
    }
    if ( statement -> state == 8 ||
            statement -> state == 9 ||
            statement -> state == 10 )
    {
        dm_log_write( "SQLBulkOperations.c",
                207,
                0,
                0,
                "Error: HY010" );
        __post_internal_error( &statement -> error,
                ERROR_HY010, ((void *)0),
                statement -> connection -> environment -> requested_version );
        return function_return_ex(3,statement,(-1),0);
    }
    if ( statement -> state == 11 ||
            statement -> state == 12 )
    {
        if ( statement -> interupted_func != 24 )
        {
            dm_log_write( "SQLBulkOperations.c",
                    225,
                    0,
                    0,
                    "Error: HY010" );
            __post_internal_error( &statement -> error,
                    ERROR_HY010, ((void *)0),
                    statement -> connection -> environment -> requested_version );
            return function_return_ex(3,statement,(-1),0);
        }
    }
    if ( (statement -> connection->functions[9].func!=((void *)0)))
    {
        ret = (statement -> connection->functions[9].func)(statement -> driver_stmt,operation);
    }
    else if ( (statement -> connection->functions[68].func!=((void *)0)) &&
            statement -> connection -> driver_act_ver == 2UL &&
            operation == 4 )
    {
        ret = (statement -> connection->functions[68].func) (statement -> driver_stmt,0,4,0);
    }
    else
    {
        dm_log_write( "SQLBulkOperations.c",
                261,
                0,
                0,
                "Error: IM001" );
        __post_internal_error( &statement -> error,
                ERROR_IM001, ((void *)0),
                statement -> connection -> environment -> requested_version );
        return function_return_ex(3,statement,(-1),0);
    }
    if ( ret == 2 )
    {
        statement -> interupted_func = 24;
        if ( statement -> state != 11 &&
                statement -> state != 12 )
            statement -> state = 11;
    }
    else if ( ret == 99 )
    {
        statement -> interupted_func = 24;
        statement -> interupted_state = statement -> state;
        statement -> state = 8;
    }
    if ( log_info.log_flag )
    {
        sprintf( statement -> msg,
                "\n\t\tExit:[%s]",
                    __get_return_status( ret, s1 ));
        dm_log_write( "SQLBulkOperations.c",
                294,
                0,
                0,
                statement -> msg );
    }
    return function_return_ex(3,statement,ret,0);
}

canonical_original_code:
short SQLBulkOperations(void *statement_handle, short operation)
{
    struct statement *statement = (DMHSTMT)statement_handle;
    short ret;
    unsigned char s1[-1];
    if ( !__validate_stmt( statement ))
    {
        dm_log_write( "SQLBulkOperations.c",
                124,
                    0,
                    0,
                    "Error: SQL_INVALID_HANDLE" );
        return (-2);
    }
    function_entry( statement );
    if ( log_info.log_flag )
    {
        sprintf( statement -> msg, "\n\t\tEntry:\n\t\t\tStatement = %p\n\t\t\tOption = %d",
                statement,
                operation );
        dm_log_write( "SQLBulkOperations.c",
                143,
                0,
                0,
                statement -> msg );
    }
    thread_protect( 3, statement );
    if ( statement -> state == 1 ||
            statement -> state == 2 ||
            statement -> state == 3 )
    {
        dm_log_write( "SQLBulkOperations.c",
                160,
                0,
                0,
                "Error: HY010" );
        __post_internal_error( &statement -> error,
                ERROR_HY010, ((void *)0),
                statement -> connection -> environment -> requested_version );
        return function_return_ex(3,statement,(-1),0);
    }
    if ( statement -> state == 4 )
    {
        dm_log_write( "SQLBulkOperations.c",
                175,
                0,
                0,
                "Error: 24000" );
        __post_internal_error( &statement -> error,
                ERROR_24000, ((void *)0),
                statement -> connection -> environment -> requested_version );
        return function_return_ex(3,statement,(-1),0);
    }
    if ( statement -> state == 7 )
    {
        dm_log_write( "SQLBulkOperations.c",
                190,
                0,
                0,
                "Error: HY010" );
        __post_internal_error( &statement -> error,
                ERROR_HY010, ((void *)0),
                statement -> connection -> environment -> requested_version );
        return function_return_ex(3,statement,(-1),0);
    }
    if ( statement -> state == 8 ||
            statement -> state == 9 ||
            statement -> state == 10 )
    {
        dm_log_write( "SQLBulkOperations.c",
                207,
                0,
                0,
                "Error: HY010" );
        __post_internal_error( &statement -> error,
                ERROR_HY010, ((void *)0),
                statement -> connection -> environment -> requested_version );
        return function_return_ex(3,statement,(-1),0);
    }
    if ( statement -> state == 11 ||
            statement -> state == 12 )
    {
        if ( statement -> interupted_func != 24 )
        {
            dm_log_write( "SQLBulkOperations.c",
                    225,
                    0,
                    0,
                    "Error: HY010" );
            __post_internal_error( &statement -> error,
                    ERROR_HY010, ((void *)0),
                    statement -> connection -> environment -> requested_version );
            return function_return_ex(3,statement,(-1),0);
        }
    }
    if ( (statement -> connection->functions[9].func!=((void *)0)))
    {
        ret = (statement -> connection->functions[9].func)(statement -> driver_stmt,operation);
    }
    else if ( (statement -> connection->functions[68].func!=((void *)0)) &&
            statement -> connection -> driver_act_ver == 2UL &&
            operation == 4 )
    {
        ret = (statement -> connection->functions[68].func) (statement -> driver_stmt,0,4,0);
    }
    else
    {
        dm_log_write( "SQLBulkOperations.c",
                261,
                0,
                0,
                "Error: IM001" );
        __post_internal_error( &statement -> error,
                ERROR_IM001, ((void *)0),
                statement -> connection -> environment -> requested_version );
        return function_return_ex(3,statement,(-1),0);
    }
    if ( ret == 2 )
    {
        statement -> interupted_func = 24;
        if ( statement -> state != 11 &&
                statement -> state != 12 )
            statement -> state = 11;
    }
    else if ( ret == 99 )
    {
        statement -> interupted_func = 24;
        statement -> interupted_state = statement -> state;
        statement -> state = 8;
    }
    if ( log_info.log_flag )
    {
        sprintf( statement -> msg,
                "\n\t\tExit:[%s]",
                    __get_return_status( ret, s1 ));
        dm_log_write( "SQLBulkOperations.c",
                294,
                0,
                0,
                statement -> msg );
    }
    return function_return_ex(3,statement,ret,0);
}

variable_types: operation short

variable_types: struct statement { int type; struct statement *next_class_list; char msg[1024]; int state; struct connection { int type; struct connection *next_class_list; char msg[1024]; int state; struct environment { int type; struct environment *next_class_list; char msg[1024]; int state; long requested_version; int connection_count; int sql_driver_count; struct error_head { struct error_header { int error_count; struct error { unsigned short sqlstate[6]; unsigned short *msg; long native_error; int return_val; short diag_column_number_ret; short diag_row_number_ret; short diag_class_origin_ret; short diag_subclass_origin_ret; short diag_connection_name_ret; short diag_server_name_ret; long diag_column_number; long diag_row_number; unsigned short diag_class_origin[128]; unsigned short diag_subclass_origin[128]; unsigned short diag_connection_name[128]; unsigned short diag_server_name[128]; struct error *next; struct error *prev; } *error_list_head; struct error *error_list_tail; int internal_count; struct error *internal_list_head; struct error *internal_list_tail; } sql_error_head; struct error_header sql_diag_head; void *owning_handle; int handle_type; short return_code; long header_set; short diag_cursor_row_count_ret; short diag_dynamic_function_ret; short diag_dynamic_function_code_ret; short diag_number_ret; short diag_row_count_ret; long diag_cursor_row_count; unsigned short diag_dynamic_function[128]; long diag_dynamic_function_code; long diag_number; long diag_row_count; } error; long connection_pooling; long cp_match; int fetch_mode; int entry; void *sh; struct env_lib_struct { char *lib_name; void *env_handle; int count; struct env_lib_struct *next; } *env_lib_list; } *environment; void *dl_handle; char dl_name[256]; struct driver_func { int ordinal; char *name; void *dm_func; void *dm_funcW; short (*func)(); short (*funcW)(); short (*funcA)(); int can_supply; } *functions; struct driver_func ini_func; struct driver_func fini_func; int unicode_driver; void *driver_env; void *driver_dbc; int driver_version; int driver_act_ver; int statement_count; struct error_head error; char dsn[-1]; int access_mode; int access_mode_set; int login_timeout; int login_timeout_set; int auto_commit; int auto_commit_set; int async_enable; int async_enable_set; int auto_ipd; int auto_ipd_set; int connection_timeout; int connection_timeout_set; int metadata_id; int metadata_id_set; int packet_size; int packet_size_set; long quite_mode; int quite_mode_set; int txn_isolation; int txn_isolation_set; long cursors; void *cl_handle; int trace; char tracefile[-1]; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } mutex; int protection_level; int ex_fetch_mapping; int disable_gf; int dont_dlclose; int bookmarks_on; void *pooled_connection; int pooling_timeout; int ttl; char driver_connect_string[1024]; int dsn_length; char server[128]; int server_length; char user[128]; int user_length; char password[128]; int password_length; char cli_year[5]; struct attr_struct { int count; struct attr_set { char *keyword; char *value; int override; int attribute; int is_int_type; int int_value; struct attr_set *next; } *list; } env_attribute; struct attr_struct dbc_attribute; struct attr_struct stmt_attribute; struct save_attr { int attr_type; char *str_attr; int str_len; int int_attr; struct save_attr *next; } *save_attr; void *iconv_cd_uc_to_ascii; void *iconv_cd_ascii_to_uc; char unicode_string[64]; struct env_lib_struct *env_list_ent; char probe_sql[512]; int threading_level; int cbs_found; short ccb_value; short crb_value; } *connection; void *driver_stmt; short hascols; int prepared; int interupted_func; int interupted_state; int bookmarks_on; struct error_head error; long metadata_id; struct descriptor { int type; struct descriptor *next_class_list; char msg[1024]; int state; struct error_head error; void *driver_desc; struct connection *connection; int implicit; void *associated_with; union pthread_mutex_t mutex; } *ipd; struct descriptor *apd; struct descriptor *ird; struct descriptor *ard; struct descriptor *implicit_ipd; struct descriptor *implicit_apd; struct descriptor *implicit_ird; struct descriptor *implicit_ard; unsigned long *fetch_bm_ptr; unsigned long *row_ct_ptr; unsigned short *row_st_arr; unsigned long row_array_size; void *valueptr; union pthread_mutex_t mutex; int eod; } *

variable_types: ret short

user_defined_types: struct statement { int type; struct statement *next_class_list; char msg[1024]; int state; struct connection *connection; void *driver_stmt; short hascols; int prepared; int interupted_func; int interupted_state; int bookmarks_on; struct error_head error; long metadata_id; struct descriptor *ipd; struct descriptor *apd; struct descriptor *ird; struct descriptor *ard; struct descriptor *implicit_ipd; struct descriptor *implicit_apd; struct descriptor *implicit_ird; struct descriptor *implicit_ard; unsigned long *fetch_bm_ptr; unsigned long *row_ct_ptr; unsigned short *row_st_arr; unsigned long row_array_size; void *valueptr; union pthread_mutex_t mutex; int eod; }

user_defined_types: struct connection { int type; struct connection *next_class_list; char msg[1024]; int state; struct environment *environment; void *dl_handle; char dl_name[256]; struct driver_func *functions; struct driver_func ini_func; struct driver_func fini_func; int unicode_driver; void *driver_env; void *driver_dbc; int driver_version; int driver_act_ver; int statement_count; struct error_head error; char dsn[-1]; int access_mode; int access_mode_set; int login_timeout; int login_timeout_set; int auto_commit; int auto_commit_set; int async_enable; int async_enable_set; int auto_ipd; int auto_ipd_set; int connection_timeout; int connection_timeout_set; int metadata_id; int metadata_id_set; int packet_size; int packet_size_set; long quite_mode; int quite_mode_set; int txn_isolation; int txn_isolation_set; long cursors; void *cl_handle; int trace; char tracefile[-1]; union pthread_mutex_t mutex; int protection_level; int ex_fetch_mapping; int disable_gf; int dont_dlclose; int bookmarks_on; void *pooled_connection; int pooling_timeout; int ttl; char driver_connect_string[1024]; int dsn_length; char server[128]; int server_length; char user[128]; int user_length; char password[128]; int password_length; char cli_year[5]; struct attr_struct env_attribute; struct attr_struct dbc_attribute; struct attr_struct stmt_attribute; struct save_attr *save_attr; void *iconv_cd_uc_to_ascii; void *iconv_cd_ascii_to_uc; char unicode_string[64]; struct env_lib_struct *env_list_ent; char probe_sql[512]; int threading_level; int cbs_found; short ccb_value; short crb_value; }

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; long __align; }

user_defined_types: struct attr_struct { int count; struct attr_set *list; }

user_defined_types: struct environment { int type; struct environment *next_class_list; char msg[1024]; int state; long requested_version; int connection_count; int sql_driver_count; struct error_head error; long connection_pooling; long cp_match; int fetch_mode; int entry; void *sh; struct env_lib_struct *env_lib_list; }

user_defined_types: struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list __list; }

user_defined_types: struct error_head { struct error_header sql_error_head; struct error_header sql_diag_head; void *owning_handle; int handle_type; short return_code; long header_set; short diag_cursor_row_count_ret; short diag_dynamic_function_ret; short diag_dynamic_function_code_ret; short diag_number_ret; short diag_row_count_ret; long diag_cursor_row_count; unsigned short diag_dynamic_function[128]; long diag_dynamic_function_code; long diag_number; long diag_row_count; }

user_defined_types: struct error_header { int error_count; struct error *error_list_head; struct error *error_list_tail; int internal_count; struct error *internal_list_head; struct error *internal_list_tail; }


SQLGetDescRec

decompiled_code:
__int64 __fastcall SQLGetDescRec(__int64 a1, __int16 a2, const char *a3, __int16 a4, _WORD *a5, const void *a6, const void *a7, const void *a8, const void *a9, const void *a10, const void *a11)
{
unsigned int v11; // er12
__int64 v15; // rax
__int64 (__fastcall *v16)(_QWORD, _QWORD, void *, _QWORD, _WORD *, const void *, const void *, const void *, const void *, const void *, const void *); // r15
__int16 v17; // bp
__int16 v18; // r15
void *v19; // rax
__int64 (__fastcall *v20)(_QWORD, _QWORD, const char *, _QWORD, _WORD *, const void *, const void *, const void *, const void *, const void *, const void *); // r10
const char *v21; // r12
const char *v22; // r15
const char *v23; // r14
const char *v24; // rax
char *sa; // [rsp+0h] [rbp-7D8h]
void *ptr; // [rsp+8h] [rbp-7D0h]
const char *ptra; // [rsp+8h] [rbp-7D0h]
const char *v29; // [rsp+10h] [rbp-7C8h]
const char *v30; // [rsp+18h] [rbp-7C0h]
char v31[240]; // [rsp+20h] [rbp-7B8h] BYREF
char v32[240]; // [rsp+110h] [rbp-6C8h] BYREF
char v33[240]; // [rsp+200h] [rbp-5D8h] BYREF
char v34[240]; // [rsp+2F0h] [rbp-4E8h] BYREF
char v35[240]; // [rsp+3E0h] [rbp-3F8h] BYREF
char v36[240]; // [rsp+4D0h] [rbp-308h] BYREF
char v37[240]; // [rsp+5C0h] [rbp-218h] BYREF
char v38[296]; // [rsp+6B0h] [rbp-128h] BYREF

LOWORD(v11) = a4;
if ( !(unsigned int)_validate_desc() )
{
dm_log_write("SQLGetDescRec.c", 216LL, 0LL, 0LL, "Error: SQL_INVALID_HANDLE");
return 4294967294LL;
}
function_entry(a1);
if ( log_info[4] )
{
sprintf(
(char *)(a1 + 16),
"\n"
"\t\tEntry:\n"
"\t\t\tDescriptor = %p\n"
"\t\t\tRec Number = %d\n"
"\t\t\tName = %p\n"
"\t\t\tBuffer length = %d\n"
"\t\t\tString Length = %p\n"
"\t\t\tType = %p\n"
"\t\t\tSub Type = %p\n"
"\t\t\tLength = %p\n"
"\t\t\tPrecision = %p\n"
"\t\t\tScale = %p\n"
"\t\t\tNullable = %p",
(const void *)a1,
(unsigned int)a2,
a3,
(unsigned int)(__int16)v11,
a5,
a6,
a7,
a8,
a9,
a10,
a11);
dm_log_write("SQLGetDescRec.c", 253LL, 0LL, 0LL, a1 + 16);
}
thread_protect(4LL, a1);
if ( *(int *)(*(_QWORD *)(a1 + 1480) + 1040LL) <= 3 )
{
dm_log_write("SQLGetDescRec.c", 264LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1048, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1480) + 1048LL) + 1048LL));
return function_return_ex(4LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( (unsigned int)_check_stmt_from_desc(a1, 8LL)
|| (unsigned int)_check_stmt_from_desc(a1, 9LL)
|| (unsigned int)_check_stmt_from_desc(a1, 10LL)
|| (unsigned int)_check_stmt_from_desc(a1, 11LL)
|| (unsigned int)_check_stmt_from_desc(a1, 12LL) )
{
dm_log_write("SQLGetDescRec.c", 287LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1048, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1480) + 1048LL) + 1048LL));
return function_return_ex(4LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( (unsigned int)_check_stmt_from_desc_ird(a1, 1LL) )
{
dm_log_write("SQLGetDescRec.c", 302LL, 0LL, 0LL, "Error: HY007");
_post_internal_error(a1 + 1048, 21LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1480) + 1048LL) + 1048LL));
return function_return_ex(4LL, a1, 0xFFFFFFFFLL, 0LL);
}
v15 = *(_QWORD *)(a1 + 1480);
if ( *(_DWORD *)(v15 + 1456) )
{
v16 = *(__int64 (__fastcall **)(_QWORD, _QWORD, void *, _QWORD, _WORD *, const void *, const void *, const void *, const void *, const void *, const void *))(*(_QWORD *)(v15 + 1320) + 2664LL);
if ( !v16 )
{
dm_log_write("SQLGetDescRec.c", 321LL, 0LL, 0LL, "Error: IM001");
_post_internal_error(a1 + 1048, 42LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1480) + 1048LL) + 1048LL));
return function_return_ex(4LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( a3 && (__int16)v11 > 0 )
{
v11 = (__int16)v11;
v19 = malloc(2LL * ((__int16)v11 + 1));
if ( v19 )
{
ptr = v19;
v17 = v16(
*(_QWORD *)(a1 + 1472),
(unsigned int)a2,
v19,
(unsigned int)(__int16)v11,
a5,
a6,
a7,
a8,
a9,
a10,
a11);
v18 = v17 & 0xFFFE;
if ( (v17 & 0xFFFE) == 0 )
unicode_to_ansi_copy(a3, (unsigned int)(__int16)v11, ptr, -3LL, *(_QWORD *)(a1 + 1480));
free(ptr);
goto LABEL_27;
}
}
else
{
v11 = (__int16)v11;
}
v17 = v16(*(_QWORD *)(a1 + 1472), (unsigned int)a2, (void *)a3, v11, a5, a6, a7, a8, a9, a10, a11);
v18 = v17 & 0xFFFE;
if ( (v17 & 0xFFFE) != 0 )
goto LABEL_32;
LABEL_27:
if ( a5 && !v18 )
*a5 = strlen(a3);
goto LABEL_32;
}
v20 = *(__int64 (__fastcall **)(_QWORD, _QWORD, const char *, _QWORD, _WORD *, const void *, const void *, const void *, const void *, const void *, const void *))(*(_QWORD *)(v15 + 1320) + 2656LL);
if ( !v20 )
{
dm_log_write("SQLGetDescRec.c", 369LL, 0LL, 0LL, "Error: IM001");
_post_internal_error(a1 + 1048, 42LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1480) + 1048LL) + 1048LL));
return function_return_ex(4LL, a1, 0xFFFFFFFFLL, 0LL);
}
v17 = v20(*(_QWORD *)(a1 + 1472), (unsigned int)a2, a3, (unsigned int)(__int16)v11, a5, a6, a7, a8, a9, a10, a11);
LABEL_32:
if ( log_info[4] )
{
v21 = (const char *)_sptr_as_string(v32, a11);
v22 = (const char *)_sptr_as_string(v33, a10);
ptra = (const char *)_sptr_as_string(v34, a9);
v29 = (const char *)_ptr_as_string(v35, a8);
v30 = (const char *)_sptr_as_string(v36, a7);
v23 = (const char *)_sptr_as_string(v37, a6);
sa = (char *)_sdata_as_string(v38, 1LL, a5, a3);
v24 = (const char *)_get_return_status((unsigned int)v17, v31);
sprintf(
(char *)(a1 + 16),
"\n"
"\t\tExit:[%s]\n"
"\t\t\tName = %s\n"
"\t\t\tType = %s\n"
"\t\t\tSub Type = %s\n"
"\t\t\tLength = %s\n"
"\t\t\tPrecision = %s\n"
"\t\t\tScale = %s\n"
"\t\t\tNullable = %s",
v24,
sa,
v23,
v30,
v29,
ptra,
v22,
v21);
dm_log_write("SQLGetDescRec.c", 417LL, 0LL, 0LL, a1 + 16);
}
return function_return_ex(4LL, a1, (unsigned int)v17, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int16 a2, const char *a3, __int16 a4, _WORD *a5, const void *a6, const void *a7, const void *a8, const void *a9, const void *a10, const void *a11)
{
unsigned int v11; // er12
__int64 v15; // rax
__int64 (__fastcall *v16)(_QWORD, _QWORD, void *, _QWORD, _WORD *, const void *, const void *, const void *, const void *, const void *, const void *); // r15
__int16 v17; // bp
__int16 v18; // r15
void *v19; // rax
__int64 (__fastcall *v20)(_QWORD, _QWORD, const char *, _QWORD, _WORD *, const void *, const void *, const void *, const void *, const void *, const void *); // r10
const char *v21; // r12
const char *v22; // r15
const char *v23; // r14
const char *v24; // rax
char *sa; // [rsp+0h] [rbp-7D8h]
void *ptr; // [rsp+8h] [rbp-7D0h]
const char *ptra; // [rsp+8h] [rbp-7D0h]
const char *v29; // [rsp+10h] [rbp-7C8h]
const char *v30; // [rsp+18h] [rbp-7C0h]
char v31[240]; // [rsp+20h] [rbp-7B8h] BYREF
char v32[240]; // [rsp+110h] [rbp-6C8h] BYREF
char v33[240]; // [rsp+200h] [rbp-5D8h] BYREF
char v34[240]; // [rsp+2F0h] [rbp-4E8h] BYREF
char v35[240]; // [rsp+3E0h] [rbp-3F8h] BYREF
char v36[240]; // [rsp+4D0h] [rbp-308h] BYREF
char v37[240]; // [rsp+5C0h] [rbp-218h] BYREF
char v38[296]; // [rsp+6B0h] [rbp-128h] BYREF

LOWORD(v11) = a4;
if ( !(unsigned int)_validate_desc() )
{
dm_log_write("SQLGetDescRec.c", 216LL, 0LL, 0LL, "Error: SQL_INVALID_HANDLE");
return 4294967294LL;
}
function_entry(a1);
if ( log_info[4] )
{
sprintf(
(char *)(a1 + 16),
"\n"
"\t\tEntry:\n"
"\t\t\tDescriptor = %p\n"
"\t\t\tRec Number = %d\n"
"\t\t\tName = %p\n"
"\t\t\tBuffer length = %d\n"
"\t\t\tString Length = %p\n"
"\t\t\tType = %p\n"
"\t\t\tSub Type = %p\n"
"\t\t\tLength = %p\n"
"\t\t\tPrecision = %p\n"
"\t\t\tScale = %p\n"
"\t\t\tNullable = %p",
(const void *)a1,
(unsigned int)a2,
a3,
(unsigned int)(__int16)v11,
a5,
a6,
a7,
a8,
a9,
a10,
a11);
dm_log_write("SQLGetDescRec.c", 253LL, 0LL, 0LL, a1 + 16);
}
thread_protect(4LL, a1);
if ( *(int *)(*(_QWORD *)(a1 + 1480) + 1040LL) <= 3 )
{
dm_log_write("SQLGetDescRec.c", 264LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1048, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1480) + 1048LL) + 1048LL));
return function_return_ex(4LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( (unsigned int)_check_stmt_from_desc(a1, 8LL)
|| (unsigned int)_check_stmt_from_desc(a1, 9LL)
|| (unsigned int)_check_stmt_from_desc(a1, 10LL)
|| (unsigned int)_check_stmt_from_desc(a1, 11LL)
|| (unsigned int)_check_stmt_from_desc(a1, 12LL) )
{
dm_log_write("SQLGetDescRec.c", 287LL, 0LL, 0LL, "Error: HY010");
_post_internal_error(a1 + 1048, 23LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1480) + 1048LL) + 1048LL));
return function_return_ex(4LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( (unsigned int)_check_stmt_from_desc_ird(a1, 1LL) )
{
dm_log_write("SQLGetDescRec.c", 302LL, 0LL, 0LL, "Error: HY007");
_post_internal_error(a1 + 1048, 21LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1480) + 1048LL) + 1048LL));
return function_return_ex(4LL, a1, 0xFFFFFFFFLL, 0LL);
}
v15 = *(_QWORD *)(a1 + 1480);
if ( *(_DWORD *)(v15 + 1456) )
{
v16 = *(__int64 (__fastcall **)(_QWORD, _QWORD, void *, _QWORD, _WORD *, const void *, const void *, const void *, const void *, const void *, const void *))(*(_QWORD *)(v15 + 1320) + 2664LL);
if ( !v16 )
{
dm_log_write("SQLGetDescRec.c", 321LL, 0LL, 0LL, "Error: IM001");
_post_internal_error(a1 + 1048, 42LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1480) + 1048LL) + 1048LL));
return function_return_ex(4LL, a1, 0xFFFFFFFFLL, 0LL);
}
if ( a3 && (__int16)v11 > 0 )
{
v11 = (__int16)v11;
v19 = malloc(2LL * ((__int16)v11 + 1));
if ( v19 )
{
ptr = v19;
v17 = v16(
*(_QWORD *)(a1 + 1472),
(unsigned int)a2,
v19,
(unsigned int)(__int16)v11,
a5,
a6,
a7,
a8,
a9,
a10,
a11);
v18 = v17 & 0xFFFE;
if ( (v17 & 0xFFFE) == 0 )
unicode_to_ansi_copy(a3, (unsigned int)(__int16)v11, ptr, -3LL, *(_QWORD *)(a1 + 1480));
free(ptr);
goto LABEL_27;
}
}
else
{
v11 = (__int16)v11;
}
v17 = v16(*(_QWORD *)(a1 + 1472), (unsigned int)a2, (void *)a3, v11, a5, a6, a7, a8, a9, a10, a11);
v18 = v17 & 0xFFFE;
if ( (v17 & 0xFFFE) != 0 )
goto LABEL_32;
LABEL_27:
if ( a5 && !v18 )
*a5 = strlen(a3);
goto LABEL_32;
}
v20 = *(__int64 (__fastcall **)(_QWORD, _QWORD, const char *, _QWORD, _WORD *, const void *, const void *, const void *, const void *, const void *, const void *))(*(_QWORD *)(v15 + 1320) + 2656LL);
if ( !v20 )
{
dm_log_write("SQLGetDescRec.c", 369LL, 0LL, 0LL, "Error: IM001");
_post_internal_error(a1 + 1048, 42LL, 0LL, *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 1480) + 1048LL) + 1048LL));
return function_return_ex(4LL, a1, 0xFFFFFFFFLL, 0LL);
}
v17 = v20(*(_QWORD *)(a1 + 1472), (unsigned int)a2, a3, (unsigned int)(__int16)v11, a5, a6, a7, a8, a9, a10, a11);
LABEL_32:
if ( log_info[4] )
{
v21 = (const char *)_sptr_as_string(v32, a11);
v22 = (const char *)_sptr_as_string(v33, a10);
ptra = (const char *)_sptr_as_string(v34, a9);
v29 = (const char *)_ptr_as_string(v35, a8);
v30 = (const char *)_sptr_as_string(v36, a7);
v23 = (const char *)_sptr_as_string(v37, a6);
sa = (char *)_sdata_as_string(v38, 1LL, a5, a3);
v24 = (const char *)_get_return_status((unsigned int)v17, v31);
sprintf(
(char *)(a1 + 16),
"\n"
"\t\tExit:[%s]\n"
"\t\t\tName = %s\n"
"\t\t\tType = %s\n"
"\t\t\tSub Type = %s\n"
"\t\t\tLength = %s\n"
"\t\t\tPrecision = %s\n"
"\t\t\tScale = %s\n"
"\t\t\tNullable = %s",
v24,
sa,
v23,
v30,
v29,
ptra,
v22,
v21);
dm_log_write("SQLGetDescRec.c", 417LL, 0LL, 0LL, a1 + 16);
}
return function_return_ex(4LL, a1, (unsigned int)v17, 0LL);
}

original_code:
SQLRETURN SQLGetDescRec( SQLHDESC DescriptorHandle,
                             SQLSMALLINT RecordNumber,
                             SQLCHAR *Name,
                             SQLSMALLINT BufferLength,
                             SQLSMALLINT *StringLength,
                             SQLSMALLINT *Type,
                             SQLSMALLINT *SubType,
                             SQLINTEGER *Length,
                             SQLSMALLINT *Precision,
                             SQLSMALLINT *Scale,
                             SQLSMALLINT *Nullable
                        )
{
    return (-1);
}

canonical_original_code:
short SQLGetDescRec(void *DescriptorHandle, short RecordNumber, unsigned char *Name, short BufferLength, short *StringLength, short *Type, short *SubType, long *Length, short *Precision, short *Scale, short *Nullable)
{
    return (-1);
}

variable_types:
DescriptorHandle
void *

variable_types: RecordNumber short

variable_types:
Name
unsigned char *

variable_types: BufferLength short

variable_types:
StringLength
short *

variable_types:
Type
short *

variable_types:
SubType
short *

variable_types:
Length
long *

variable_types:
Precision
short *

variable_types:
Scale
short *

variable_types:
Nullable
short *


SQLSetConfigMode

decompiled_code:
__int64 __fastcall SQLSetConfigMode(unsigned __int16 a1)
{
inst_logClear();
_set_config_mode(a1);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned __int16 a1)
{
inst_logClear();
func0(a1);
return 1LL;
}

original_code:
int SQLSetConfigMode( UWORD nConfigMode )
{
    inst_logClear();
    __set_config_mode( nConfigMode );
    return 1;
}

canonical_original_code:
int SQLSetConfigMode(unsigned short nConfigMode)
{
    inst_logClear();
    __set_config_mode( nConfigMode );
    return 1;
}

variable_types:
nConfigMode
unsigned short