static USHORT get_capabilities(ISC_STATUS* user_status) { struct isc_4_struct { short isc_5; /* isc_utility */ } isc_4; struct isc_1_struct { char isc_2 [32]; /* RDB$FIELD_NAME */ char isc_3 [32]; /* RDB$RELATION_NAME */ } isc_1; USHORT capabilities = CAP_none; AliceGlobals* tdgbl = AliceGlobals::getSpecific(); // Look for desired fields in system relations FB_API_HANDLE req = 0; for (const rfr_tab_t* rel_field_table = rfr_table; rel_field_table->relation; rel_field_table++) { /*FOR(REQUEST_HANDLE req) x IN DB.RDB$RELATION_FIELDS WITH x.RDB$RELATION_NAME = rel_field_table->relation AND x.RDB$FIELD_NAME = rel_field_table->field*/ { if (!req) isc_compile_request (isc_status, (FB_API_HANDLE*) &DB, (FB_API_HANDLE*) &req, (short) sizeof(isc_0), (char*) isc_0); isc_vtov ((const char*) rel_field_table->field, (char*) isc_1.isc_2, 32); isc_vtov ((const char*) rel_field_table->relation, (char*) isc_1.isc_3, 32); if (req) isc_start_and_send (isc_status, (FB_API_HANDLE*) &req, (FB_API_HANDLE*) &gds_trans, (short) 0, (short) 64, &isc_1, (short) 0); if (!isc_status [1]) { while (1) { isc_receive (isc_status, (FB_API_HANDLE*) &req, (short) 1, (short) 2, &isc_4, (short) 0); if (!isc_4.isc_5 || isc_status [1]) break; capabilities |= rel_field_table->bit_mask; /*END_FOR*/ } }; /*ON_ERROR*/ if (isc_status [1]) { return_error(user_status); /*END_ERROR;*/ } } } isc_release_request(gds_status, &req); if (gds_status[1]) { return_error(user_status); } return capabilities; }
void detectRuntimeODS() { struct isc_4_struct { short isc_5; /* isc_utility */ } isc_4; struct isc_1_struct { char isc_2 [32]; /* RDB$FIELD_NAME */ char isc_3 [32]; /* RDB$RELATION_NAME */ } isc_1; struct isc_9_struct { short isc_10; /* isc_utility */ } isc_9; struct isc_7_struct { char isc_8 [32]; /* RDB$RELATION_NAME */ } isc_7; struct isc_12_struct { short isc_13; /* isc_utility */ } isc_12; /************************************** * * d e t e c t R u n t i m e O D S * ************************************** * * Functional description * Find the ODS version number of the database. * Use system_flag to avoid any possibility of ambiguity (someone using the rdb$ prefix). * **************************************/ BurpGlobals* tdgbl = BurpGlobals::getSpecific(); tdgbl->runtimeODS = 0; // Detect very old server before IB4 just in case to exit gracefully. // select count(*) from rdb$relation_fields // where rdb$relation_name in ('RDB$RELATIONS', 'RDB$RELATION_FIELDS') // and rdb$field_name = 'RDB$SYSTEM_FLAG'; int count = 0; isc_req_handle req_handle = 0; /*FOR (REQUEST_HANDLE req_handle) RFR IN RDB$RELATION_FIELDS WITH (RFR.RDB$RELATION_NAME = 'RDB$RELATIONS' OR RFR.RDB$RELATION_NAME = 'RDB$RELATION_FIELDS') AND RFR.RDB$FIELD_NAME = 'RDB$SYSTEM_FLAG'*/ { if (!req_handle) isc_compile_request (isc_status, (FB_API_HANDLE*) &DB, (FB_API_HANDLE*) &req_handle, (short) sizeof(isc_11), (char*) isc_11); if (req_handle) isc_start_request (isc_status, (FB_API_HANDLE*) &req_handle, (FB_API_HANDLE*) &gds_trans, (short) 0); if (!isc_status [1]) { while (1) { isc_receive (isc_status, (FB_API_HANDLE*) &req_handle, (short) 0, (short) 2, &isc_12, (short) 0); if (!isc_12.isc_13 || isc_status [1]) break; ++count; /*END_FOR;*/ } }; /*ON_ERROR*/ if (isc_status [1]) { general_on_error(); /*END_ERROR;*/ } } MISC_release_request_silent(req_handle); if (count != 2) return; isc_req_handle req_handle2 = 0; for (const rel_field_t* rel = relations; rel->relation; ++rel) { /*FOR (REQUEST_HANDLE req_handle2) FIRST 1 X IN RDB$RELATIONS WITH X.RDB$RELATION_NAME = rel->relation AND X.RDB$SYSTEM_FLAG = 1*/ { if (!req_handle2) isc_compile_request (isc_status, (FB_API_HANDLE*) &DB, (FB_API_HANDLE*) &req_handle2, (short) sizeof(isc_6), (char*) isc_6); isc_vtov ((const char*) rel->relation, (char*) isc_7.isc_8, 32); if (req_handle2) isc_start_and_send (isc_status, (FB_API_HANDLE*) &req_handle2, (FB_API_HANDLE*) &gds_trans, (short) 0, (short) 32, &isc_7, (short) 0); if (!isc_status [1]) { while (1) { isc_receive (isc_status, (FB_API_HANDLE*) &req_handle2, (short) 1, (short) 2, &isc_9, (short) 0); if (!isc_9.isc_10 || isc_status [1]) break; if (tdgbl->runtimeODS < rel->ods_version) tdgbl->runtimeODS = rel->ods_version; /*END_FOR;*/ } }; /*ON_ERROR*/ if (isc_status [1]) { general_on_error(); /*END_ERROR;*/ } } } MISC_release_request_silent(req_handle2); if (tdgbl->runtimeODS < DB_VERSION_DDL8) return; isc_req_handle req_handle3 = 0; for (const rel_field_t* rf = rel_fields; rf->relation; ++rf) { /*FOR (REQUEST_HANDLE req_handle3) FIRST 1 X2 IN RDB$RELATION_FIELDS WITH X2.RDB$RELATION_NAME = rf->relation AND X2.RDB$FIELD_NAME = rf->field AND X2.RDB$SYSTEM_FLAG = 1*/ { if (!req_handle3) isc_compile_request (isc_status, (FB_API_HANDLE*) &DB, (FB_API_HANDLE*) &req_handle3, (short) sizeof(isc_0), (char*) isc_0); isc_vtov ((const char*) rf->field, (char*) isc_1.isc_2, 32); isc_vtov ((const char*) rf->relation, (char*) isc_1.isc_3, 32); if (req_handle3) isc_start_and_send (isc_status, (FB_API_HANDLE*) &req_handle3, (FB_API_HANDLE*) &gds_trans, (short) 0, (short) 64, &isc_1, (short) 0); if (!isc_status [1]) { while (1) { isc_receive (isc_status, (FB_API_HANDLE*) &req_handle3, (short) 1, (short) 2, &isc_4, (short) 0); if (!isc_4.isc_5 || isc_status [1]) break; if (tdgbl->runtimeODS < rf->ods_version) tdgbl->runtimeODS = rf->ods_version; /*END_FOR;*/ } }; /*ON_ERROR*/ if (isc_status [1]) { general_on_error(); /*END_ERROR;*/ } } } MISC_release_request_silent(req_handle3); }