** _______ _______ _______ _______ _______ _______ ______ _______ _______ ______ _______ ** | _ | _ | _ | | | _ | || _ | _ | _ | | _ | ** | |_| | |_| | |_| | _ | | |_| | _ | |_| | |_| | | || | |_| | ** | | | | |_| | | | | | | | | |_||_| | ** | | _ || | ___| _| | |_| | | _ || __ | | ** | _ | |_| | _ | | | |_| _ | | _ | |_| | | | | _ | ** |__| |__|_______|__| |__|___| |_______|__| |__|______||__| |__|_______|___| |_|__| |__| ** www.abapcadabra.com **------------------------------------------------------------------------------------------- ** ** ___ __ __ _ _ ** / __\ ___ _ __ _ _ / / /\ \ \ _ __ (_)| |_ ___ _ __ ** / / / _ \ | '_ \ | | | |\ \/ \/ /| '__|| || __| / _ \| '__| ** / /___ | (_) || |_) || |_| | \ /\ / | | | || |_ | __/| | ** \____/ \___/ | .__/ \__, | \/ \/ |_| |_| \__| \___||_| ** |_| |___/ Cloack and uncloack your coding ** **------------------------------------------------------------------------------------------- ** program : ZABAPCADABRA_COPYWRITER ** title : AbapcadabrA CopyWriter, Copy-protect your coding, hang on to original ** functional area : Development tool ** environment : 4.7 ** program Function : Utility tool to protect installed software. The report will clear ** all comments and formatting and rename local variables from methods ** and routines to HEX guid codes. The original source can be re-instated ** but is kept in a password protected storage, where the password was ** used to scramble the source. ** Documentation : Search for "Copywriter" on AbapcadabrA.com ** Previous version : This is the initial version ** Developer name : Wim Maasdam, Ogre full ** Development date : 01/11/2016, final release 08/11/2016 ** Version : 0.2 **------------------------------------------------------------------------------------------- * __ __ _ * __/\____/\__ / / /\ \ \ __ _ _ __ _ __ (_) _ __ __ _ __/\____/\__ * \ /\ / \ \/ \/ / / _` || '__|| '_ \ | || '_ \ / _` | \ /\ / * /_ _\/_ _\ \ /\ / | (_| || | | | | || || | | || (_| | /_ _\/_ _\ * \/ \/ \/ \/ \__,_||_| |_| |_||_||_| |_| \__, | \/ \/ * |___/ * .--. .--. * (O)(O) This report will overwrite the content of other reports and should NEVER (O)(O) * | o / be used in test or production systems. Before using this report, make sure | o / * |`-/ it is tested on your system. The report will remove (and rebuild) all coding |`-/ * |_/ in report or include, without altering the way the coding works. The |_/ * _ copywriter effectively tranforms Abap logic into a form that is unfriendly _ * (_) to the human eye. Restore before applying any changes to the coding. (_) * * YOU SHOULD HAVE A BACKUP OF YOUR CODING WHEN USING THIS COPYRIGHT MECHANISM * IT MAY WORK BETTER THAN EXPECTED (LOST PASSWORD) OR IT MAY BE DAMAGED (CODING * CHANGE THAT AFFECTS THE ENCRYPTION/DECRYPTION MECHANISM). * *------------------------------------------------------------------------------------------- * Change list: * Date Description * 01/11/2016 Initial release * 01/11/2016 Macro support, Copywriter directives for comments and search and replace *------------------------------------------------------------------------------------------- * Copywriter: LCL_COPYWRITER, CONSTRUCTOR, F4_SOURCE, GET_PASSWORD, IS_PRODCTION_SYSTEM, * Copywriter: REINSTATE_CODING, SAVE_AND_STORE, SCRAMBLE_CODING, SCRAMBLE_OR_REINSTATE, * Copywriter: SET_TRANSLATION_STR, GV_ENCODING_REQUESTS REPORT ZABAPCADABRA_COPYWRITER. data: gv_encoding_requests type boolean. data: lv_srtfd type hlpindx-srtfd, lv_devclass type tadir-devclass, lv_state type progdir-state. CLASS lcl_copywriter DEFINITION. PUBLIC SECTION. DATA: gv_LEGAL_CHARS type c length 76 value 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789[]()<>!?:.,;-_', gt_WARNING_comments type standard table of char255 ##NEEDED, gt_COPYRIGHT type standard table of char50, gv_TRANSLATION_str type char255, gv_password type char20, gv_password2 type char20, gv_copyright_owner type c length 50, gv_syntax_check type boolean, gv_decode_requested type boolean, gt_source type standard table of char255, gt_source_original type standard table of char255, begin of gw_proceslog, scrambled type n length 2, scrambled_light type n length 2, scrambled_linecount type n length 8, unscrambled type n length 2, original_linecount type n length 8, skipped type n length 2, message type c length 90, end of gw_proceslog. METHODS: constructor, get_password importing title type any returning value(password) type char20, scramble_or_reinstate importing source type sy-repid, scramble_coding importing source type sy-repid, reinstate_coding importing source type sy-repid, save_and_store importing source type sy-repid, set_translation_str importing seed type any object type any. CLASS-METHODS: f4_source importing parsource type any, is_production_system returning value(is_production) type boolean.. ENDCLASS. CLASS lcl_copywriter IMPLEMENTATION. method constructor. define add_line. append &1 to gt_WARNING_comments. end-of-definition. define add_character. append &1 to gt_COPYRIGHT. end-of-definition. * Compose the *WARNING* header: clear: gt_WARNING_comments[]. add_line: '* ___ _ _ ', '*__/\____/\____/\__ / _ \ | ___ __ _ ___ ___ _ __ ___ | |_ ___ _ ', '*\ /\ /\ / / /_)/ |/ _ \/ _` / __|/ _ \ | ''_ \ / _ \| __/ _ (_)', '*/_ _\/_ _\/_ _\ / ___/| | __/ (_| \__ \ __/ | | | | (_) | || __/_ ', '* \/ \/ \/ \/ |_|\___|\__,_|___/\___| |_| |_|\___/ \__\___(_)', '* _ _ _ _ _ _ ', '*| |_| |__ (_)___ /_\ | |__ __ _ _ __ ___ ___ _ _ _ __ ___ ___ ___ ___ __| | ___ ', '*| __| ''_ \| / __| //_\\| ''_ \ / _` | ''_ \ / __|/ _ \| | | | ''__/ __/ _ \ / __/ _ \ / _` |/ _ \', '*| |_| | | | \__ \ / _ \ |_) | (_| | |_) | \__ \ (_) | |_| | | | (_| __/ | (_| (_) | (_| | __/', '* \__|_| |_|_|___/ \_/ \_/_.__/ \__,_| .__/ |___/\___/ \__,_|_| \___\___| \___\___/ \__,_|\___|', '* |_| _ _ _ ', '*__ ____ _ ___ ___ ___ _ __ _ _ _ __ _ __ ___ | |_ ___ ___| |_ ___ __| |', '*\ \ /\ / / _` / __| / __/ _ \| ''_ \| | | |_____| ''_ \| ''__/ _ \| __/ _ \/ __| __/ _ \/ _` |', '* \ V V / (_| \__ \ | (_| (_) | |_) | |_| |_____| |_) | | | (_) | || __/ (__| || __/ (_| |', '* \_/\_/ \__,_|___/ \___\___/| .__/ \__, | | .__/|_| \___/ \__\___|\___|\__\___|\__,_|', '* |_| |___/ |_| ', '* +-------------------------------------------------------------------------------------------+', '* | The Abap source code has undergone a copyright treatment which makes understanding and |', '* | changing the coding very difficult. Use report ZABAPCADABRA_COPYWRITER to reinstate the | ', '* | original coding before applying any changes or even investigating issues. For more info |', '* | on the password protected Copywrite protector search for Copywriter on AbapcadabrA.com |', '* +-------------------------------------------------------------------------------------------+', '*', '*'. add_character: ' ___ ', ' / __\', ' / / ', '/ /___ ', '\____/ ', ' ___ ', ' / _ \ ', '| (_) |', ' \___/ ', ' _ __ ', '| ''_ \ ', '| |_) |', '| .__/ ', '|_| ', ' _ _ ', '| | | |', '| |_| |', ' \__, |', ' |___/ ', ' _ __ ', '| ''__| ', '| | ', '|_| ', ' _ ', '(_) ', '| | ', '| | ', '|_| ', ' __ _ ', ' / _` |', '| (_| |', ' \__, |', ' |___/ ', ' _ ', '| |__ ', '| ''_ \ ', '| | | |', '|_| |_|', ' _ ', '| |_ ', '| __| ', '| |_ ', ' \__| ', '',''. endmethod. method get_password. data: lt_fields type STANDARD TABLE OF SVAL, lw_field type SVAL, lv_returncode type c length 1. * Request the password, for direct check and scramble seed.. clear lt_fields[]. lw_field-tabname = 'PA0367'. lw_field-fieldname = 'ANGT0'. lw_field-FIELDTEXT = 'Access code'. lw_field-NOVALUEHLP = abap_true. append lw_field to lt_fields. CALL FUNCTION 'POPUP_GET_VALUES' EXPORTING popup_title = title IMPORTING returncode = lv_returncode tables fields = lt_fields. if lv_returncode = 'A'. message 'Operation cancelled' type 'W'. leave program. endif. read table lt_fields index 1 into lw_field. * Scramble the password CALL FUNCTION 'SCRAMBLE_STRING' EXPORTING source = lw_field-value KEY = 19732835 IMPORTING TARGET = password. endmethod. method scramble_or_reinstate. data: lv_password type char20, lv_name type TRDIR-NAME, lv_devclass type tadir-devclass, lv_state type PROGDIR-state. if source is initial or source = sy-repid. exit. endif. select single devclass from tadir into lv_devclass where pgmid = 'R3TR' and object = 'PROG' and obj_name = source. if sy-subrc <> 0 or not ( lv_devclass(1) co '$YZ' ). add 1 to gw_proceslog-skipped. exit. endif. select single devclass from tadir into lv_devclass where pgmid = 'R3TR' and object = 'PROG' and obj_name = sy-repid. if sy-subrc <> 0 or ( lv_devclass <> '$TMP' ). add 1 to gw_proceslog-skipped. exit. endif. select single state from PROGDIR into lv_state where name = source and state = 'I'. if sy-subrc = 0. add 1 to gw_proceslog-skipped. exit. endif. * The abap editor lock: lv_name = source. CALL FUNCTION 'ENQUEUE_ESRDIRE' EXPORTING MODE_TRDIR = 'E' NAME = lv_name EXCEPTIONS OTHERS = 4. IF sy-subrc <> 0. message 'Editor lock' type 'I'. add 1 to gw_proceslog-skipped. exit. ENDIF. if is_production_system( ) = abap_true. add 1 to gw_proceslog-skipped. exit. endif. * Read the password from the file: import password = lv_password from database HLPINDX(ZC) id source. if sy-subrc = 0. if lv_password <> gv_password. message 'Password failure' type 'S'. leave PROGRAM. endif. gv_decode_requested = abap_true. reinstate_coding( source ). else. gv_decode_requested = abap_false. scramble_coding( source ). endif. endmethod. method scramble_coding. types: begin of lty_blindmaker, name type c length 30, guid type c length 32, len type i, end of lty_blindmaker. data: lt_tokens type standard table of STOKES, lw_token type STOKES, lt_statements type standard table of SSTMNT, lw_statement type SSTMNT, lv_sourceline type char255, lt_directives type standard table of lty_blindmaker, lt_directive_tokens type standard table of char50, lt_comments type standard table of char255, begin of lw_footpath_method, token_class type boolean, token_implementation type boolean, token_method type boolean, toggle_token_data type boolean, local_variables type standard table of lty_blindmaker with DEFAULT KEY, end of lw_footpath_method, begin of lw_footpath_routine, token_form type boolean, toggle_token_data type boolean, local_variables type standard table of lty_blindmaker with DEFAULT KEY, end of lw_footpath_routine, lw_blindmaker type lty_blindmaker, lv_copyright_charcounter type i, lv_macro_toggle type boolean, lv_charpart type char50, lv_charpart2 type char50, lv_light type boolean, lv_strlen type sy-fdpos, lv_linecount type n length 8. define writeln. add 1 to lv_copyright_charcounter. read table gt_copyright into lv_charpart index lv_copyright_charcounter. if sy-subrc <> 0. lv_copyright_charcounter = 1. read table gt_copyright into lv_charpart index lv_copyright_charcounter. endif. if not gv_copyright_owner is initial. if strlen( lv_sourceline ) < 50. lv_sourceline+50(2) = '" '. lv_sourceline+52(9) = lv_charpart. lv_sourceline+61(50) = gv_copyright_owner. endif. endif. shift lv_sourceline right by 2 places. append lv_sourceline to gt_source. clear lv_sourceline. end-of-definition. define search_and_replace. " lw_blindmaker-name lw_token-str lw_blindmaker-guid. lv_strlen = strlen( &1 ). if strlen( &2 ) >= lv_strlen. if &1 = &2(lv_strlen). REPLACE &1 IN &2 WITH &3. else. concatenate '(' &1 into lv_charpart. concatenate '(' &3 into lv_charpart2. REPLACE lv_charpart IN &2 WITH lv_charpart2. concatenate '+' &1 into lv_charpart. concatenate '+' &3 into lv_charpart2. REPLACE lv_charpart IN &2 WITH lv_charpart2. endif. endif. end-of-definition. define search_and_replace2. REPLACE &1 IN &2 WITH &3. end-of-definition. clear gt_source[]. READ REPORT source INTO gt_source. if sy-subrc <> 0. exit. endif. gt_source_original[] = gt_source[]. set_translation_str( exporting seed = gv_password object = source ). loop at gt_source_original into lv_sourceline. translate lv_sourceline USING gv_TRANSLATION_str. modify gt_source_original from lv_sourceline. endloop. describe table gt_source lines lv_linecount. add lv_linecount to gw_proceslog-original_linecount. clear: lt_comments. * A comment block with ** lines is processed as single * lines, for report headings only loop at gt_source into lv_sourceline where table_line(2) = '**'. append lv_sourceline+1 to lt_comments. delete gt_source. endloop. clear: lt_directives[], lv_light. * Filter out the copywriter directives - which are held in comments: loop at gt_source into lv_sourceline where table_line(1) = '*'. condense lv_sourceline NO-GAPS. TRANSLATE lv_sourceline to upper case. if lv_sourceline(12) = '*COPYWRITER:'. split lv_sourceline+12 at ',' into table lt_directive_tokens. loop at lt_directive_tokens into lv_charpart. if lv_charpart = 'LIGHT'. lv_light = abap_true. else. lw_blindmaker-name = lv_charpart. lw_blindmaker-len = strlen( lw_blindmaker-name ). lw_blindmaker-guid = CL_SYSTEM_UUID=>IF_SYSTEM_UUID_STATIC~CREATE_UUID_C32( ). shift lw_blindmaker-guid left by 2 places. "Length 32 to 30 lw_blindmaker-guid(2) = 'HX'. append lw_blindmaker to lt_directives. sort lt_directives by len descending name guid. endif. endloop. endif. endloop. * Coding is rebuild from SCAN tokens SCAN ABAP-SOURCE gt_source TOKENS INTO lt_tokens STATEMENTS INTO lt_statements. * Macro coding is altered to upper cased. clear: lv_macro_toggle. loop at lt_tokens into lw_token. if lw_token-str = 'DEFINE'. lv_macro_toggle = abap_true. elseif lw_token-str = 'END-OF-DEFINITION'. lv_macro_toggle = abap_false. elseif lv_macro_toggle = abap_true. if lw_token-str(1) <> ''''. TRANSLATE lw_token-str TO UPPER CASE. endif. modify lt_tokens from lw_token. endif. endloop. * There are 2 scramble methods, one that transforms macro coding into uppercased coding * and one that leaves Macro coding in tact. Directive: MACRO-SENSITIVE if lv_light = abap_true. clear: gt_source[], lv_macro_toggle. add 1 to gw_proceslog-scrambled_light. loop at lt_statements into lw_statement. clear: lv_sourceline. loop at lt_tokens from lw_statement-from to lw_statement-to into lw_token. if lw_token-str = 'DEFINE'. lv_macro_toggle = abap_true. elseif lw_token-str = 'END-OF-DEFINITION'. lv_macro_toggle = abap_false. endif. if not lt_directives[] is initial. loop at lt_directives into lw_blindmaker. search_and_replace2 lw_blindmaker-name lw_token-str lw_blindmaker-guid. endloop. endif. concatenate lv_sourceline lw_token-str into lv_sourceline SEPARATED BY space. if lv_macro_toggle = abap_true. lv_strlen = strlen( lv_sourceline ) - 1. if lv_sourceline+lv_strlen(1) = '.' or lv_sourceline+lv_strlen(1) = ','. writeln. endif. endif. * Cater for "long lines", e.g. function module calls: if strlen( lv_sourceline ) > 100. writeln. endif. endloop. concatenate lv_sourceline '.' into lv_sourceline. writeln. endloop. else. clear: gt_source[], lw_footpath_method. add 1 to gw_proceslog-scrambled. loop at lt_statements into lw_statement. * if lw_statement-trow between 610 and 611. * break-point. * endif. loop at lt_tokens from lw_statement-from to lw_statement-to into lw_token. case lw_token-str. when 'CLASS'. if lw_token-col <= 4. "Differeniate: class as definition or field name clear lw_footpath_method. lw_footpath_method-token_class = abap_true. endif. when 'IMPLEMENTATION'. if lw_footpath_method-token_class = abap_true. lw_footpath_method-token_implementation = abap_true. endif. when 'METHOD'. if lw_footpath_method-token_implementation = abap_true. lw_footpath_method-token_method = abap_true. endif. when 'DATA'. if lw_footpath_method-token_method = abap_true. lw_footpath_method-toggle_token_data = abap_true. endif. if lw_footpath_routine-token_form = abap_true. lw_footpath_routine-toggle_token_data = abap_true. endif. when 'ENDMETHOD'. clear lw_footpath_method-token_method. clear lw_footpath_method-toggle_token_data. clear lw_footpath_method-local_variables[]. when 'ENDCLASS'. clear lw_footpath_method. clear lw_footpath_method-local_variables[]. when 'FORM'. if lw_token-col <= 4. "Differeniate: routine as definition or field name clear lw_footpath_routine. lw_footpath_routine-token_form = abap_true. endif. when 'ENDFORM'. clear lw_footpath_routine. clear lw_footpath_routine-local_variables[]. endcase. lv_sourceline = lw_token-str. * Detect new local variables, on methods if lw_footpath_method-token_method = abap_true. if ( strlen( lw_token-str ) >= 3 ) and lw_token-str <> 'DATA' and lw_footpath_method-toggle_token_data = abap_true. * Cater for BEGIN OF definitions, which also have an END OF if lw_token-str(3) = 'LV_' or lw_token-str(3) = 'LW_' or lw_token-str(3) = 'LT_' or lw_token-str(3) = 'LO_' or lw_token-str(3) = 'LR_'. read table lw_footpath_method-local_variables into lw_blindmaker with key name = lw_token-str. if sy-subrc = 0. * Variable defined in BEGIN OF setup.. else. lw_blindmaker-name = lw_token-str. lw_blindmaker-len = strlen( lw_token-str ). lw_blindmaker-guid = CL_SYSTEM_UUID=>IF_SYSTEM_UUID_STATIC~CREATE_UUID_C32( ). shift lw_blindmaker-guid left by 2 places. lw_blindmaker-guid(2) = 'HX'. append lw_blindmaker to lw_footpath_method-local_variables. sort lw_footpath_method-local_variables by len descending name guid. endif. lw_footpath_method-toggle_token_data = abap_false. lv_sourceline = lw_blindmaker-guid. else. lv_sourceline = lw_token-str. endif. * Detect use of local variables elseif lw_token-str <> 'DATA' and not lw_footpath_method-local_variables[] is initial. loop at lw_footpath_method-local_variables into lw_blindmaker. search_and_replace lw_blindmaker-name lw_token-str lw_blindmaker-guid. endloop. lv_sourceline = lw_token-str. else. lv_sourceline = lw_token-str. endif. endif. * Detect new local variables, on routines if lw_footpath_routine-token_form = abap_true. if ( strlen( lw_token-str ) >= 3 ) and lw_token-str <> 'DATA' and lw_footpath_routine-toggle_token_data = abap_true. * Cater for BEGIN OF definitions, which also have an END OF if lw_token-str(3) = 'LV_' or lw_token-str(3) = 'LW_' or lw_token-str(3) = 'LT_' or lw_token-str(3) = 'LO_' or lw_token-str(3) = 'LR_'. read table lw_footpath_routine-local_variables into lw_blindmaker with key name = lw_token-str. if sy-subrc = 0. * Variable defined in BEGIN OF setup.. else. lw_blindmaker-name = lw_token-str. lw_blindmaker-len = strlen( lw_token-str ). lw_blindmaker-guid = CL_SYSTEM_UUID=>IF_SYSTEM_UUID_STATIC~CREATE_UUID_C32( ). shift lw_blindmaker-guid left by 2 places. lw_blindmaker-guid(2) = 'HX'. append lw_blindmaker to lw_footpath_routine-local_variables. sort lw_footpath_routine-local_variables by len descending name guid. endif. lw_footpath_routine-toggle_token_data = abap_false. lv_sourceline = lw_blindmaker-guid. else. lv_sourceline = lw_token-str. endif. * Detect use of local variables elseif lw_token-str <> 'DATA' and not lw_footpath_routine-local_variables[] is initial. lv_sourceline = lw_token-str. loop at lw_footpath_routine-local_variables into lw_blindmaker. search_and_replace lw_blindmaker-name lw_token-str lw_blindmaker-guid. endloop. else. lv_sourceline = lw_token-str. endif. endif. * Non local matters if not lt_directives[] is initial. loop at lt_directives into lw_blindmaker. search_and_replace2 lw_blindmaker-name lw_token-str lw_blindmaker-guid. endloop. endif. writeln. endloop. lv_sourceline = '.'. writeln. endloop. endif. * Finally: set the report "Warning - copy-protected coding" comments in the report * comment heading. insert lines of gt_WARNING_comments into gt_source index 1. * And the frozen comments or ** comment heading: insert lines of lt_comments into gt_source index 1. describe table gt_source lines lv_linecount. add lv_linecount to gw_proceslog-scrambled_linecount. save_and_store( source ). endmethod. method reinstate_coding. data: lv_sourceline type char255, lv_linecount type n length 8. clear gt_source[]. import source = gt_source from database HLPINDX(ZC) id source. check not gt_source[] is initial. set_translation_str( exporting seed = gv_password object = source ). loop at gt_source into lv_sourceline. translate lv_sourceline USING gv_TRANSLATION_str. modify gt_source from lv_sourceline. endloop. add 1 to gw_proceslog-unscrambled. describe table gt_source lines lv_linecount. add lv_linecount to gw_proceslog-original_linecount. save_and_store( source ). endmethod. method save_and_store. TYPE-POOLS: synt. data: lv_info type char255, lw_dir TYPE trdir, lt_warnings TYPE synt_errors, lv_error_message TYPE string, "#EC NEEDED lv_error_line TYPE i, "#EC NEEDED lv_error_line_c type c length 6, lv_error_word TYPE string, "#EC NEEDED lv_sourceline type char255, lv_answer type c length 1, lv_linecounter type i. * Whether it's for deactivation or activation, the coding that is locked or unlocked * should have a healthy state, thus it should pass the Abap syntax checker. If it doesn't * the user is notified: if gv_decode_requested = abap_false and gv_syntax_check = abap_true. SYNTAX-CHECK FOR gt_SOURCE MESSAGE lv_error_message LINE lv_error_line WORD lv_error_word PROGRAM source ID 'MSG' TABLE lt_warnings. if not lv_error_message is initial. if lv_error_line > 10. subtract 10 from lv_error_line. endif. write: / sy-uline(100), / 'Program: ', (90) source color 1, / 'Message: ', (90) lv_error_message color 6 intensified off, / sy-uline(100). clear: lv_linecounter. loop at gt_source into lv_sourceline from lv_error_line. if lv_linecounter = 10. write: /(100) lv_sourceline color 3 intensified on. else. write: /(100) lv_sourceline color 2 intensified off. endif. add 1 to lv_linecounter. if lv_linecounter = 20. exit. endif. endloop. write: / sy-uline(100). skip. exit. "Explicit departure of the method. endif. endif. if gv_decode_requested = abap_false. write: sy-datum DD/MM/YYYY to lv_info. write: sy-uzeit using EDIT MASK '__:__:__' to lv_info+11. concatenate lv_info sy-uname into lv_info separated by space. * The request is to ENCODE, thus snippets are stored and the report is * overwritten with a stripped version. *-------------------------------------------------------------------- export password = gv_password source = gt_source_original info = lv_info to database HLPINDX(ZC) id source. if sy-subrc = 0. *-------------------------------------------------------------------- INSERT REPORT source FROM gt_SOURCE. *-------------------------------------------------------------------- endif. else. *-------------------------------------------------------------------- INSERT REPORT source FROM gt_SOURCE. if sy-subrc = 0. *-------------------------------------------------------------------- delete from database HLPINDX(ZC) id source. *-------------------------------------------------------------------- endif. endif. endmethod. method set_translation_str. data: lv_seed type c length 40, lv_position type sy-index, begin of lw_randomizer, hash type c length 76, strlen type sy-fdpos, length type sy-fdpos, mod type sy-fdpos, end of lw_randomizer, lv_translation type c length 76. FIELD-SYMBOLS type c. * Transform SEED into a number, from 1 to 999: concatenate seed object into lv_seed. translate lv_seed TO UPPER CASE. translate lv_seed USING 'A3B4C2D3E4F5G6H7I8J9K5L6M2N3O4P5Q6R7S8T9U7V8W2X3Y4Z5~6@7&8^9#9!2?2%3=4(5)6_7-8+9:3;2|3\4/5>60718'. clear lw_randomizer. lw_randomizer-strlen = strlen( lv_seed ) - 1. lw_randomizer-hash = lv_seed. lv_translation = gv_LEGAL_CHARS. do lw_randomizer-strlen times. move lw_randomizer-hash(1) to lw_randomizer-length. assign lv_translation(lw_randomizer-length) to . lw_randomizer-mod = lw_randomizer-length mod 3. case lw_randomizer-mod. when 0. shift right by 5 places CIRCULAR. when 1. shift left by 3 places CIRCULAR. when 2. shift left by 1 places CIRCULAR. endcase. shift lv_translation right by 1 places circular. shift lw_randomizer-hash left by 1 places. enddo. clear: gv_TRANSLATION_str. lw_randomizer-strlen = strlen( lv_translation ). do lw_randomizer-strlen times. lv_position = sy-index - 1. if gv_decode_requested = abap_false. concatenate gv_TRANSLATION_str gv_LEGAL_CHARS+lv_position(1) lv_translation+lv_position(1) into gv_TRANSLATION_str. else. concatenate gv_TRANSLATION_str lv_translation+lv_position(1) gv_LEGAL_CHARS+lv_position(1) into gv_TRANSLATION_str. endif. enddo. endmethod. method f4_source. TYPES: BEGIN OF lty_columns, source type tadir-OBJ_NAME, info type TKV02-awstx, END OF lty_columns. DATA: lt_columns TYPE STANDARD TABLE OF lty_columns, lw_column type lty_columns, lv_dynprofield type HELP_INFO-DYNPROFLD, lt_sources type standard table of hlpindx-srtfd, lv_info type char255. clear: lt_columns[]. select srtfd from hlpindx into table lt_sources where relid = 'ZC' and srtf2 = 0. * Set selection values / note this is just for example purpose: loop at lt_sources into lw_column-source. import info = lv_info from database HLPINDX(ZC) id lw_column-source. lw_column-info = lv_info. APPEND lw_column to lt_columns. endloop. lv_dynprofield = parsource. CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST' EXPORTING retfield = 'SOURCE' dynpprog = SY-REPID dynpnr = '1000' dynprofield = lv_dynprofield value_org = 'S' TABLES value_tab = lt_columns. endmethod. method is_production_system. data: lv_cccategory type t000-cccategory. * Get system category select single cccategory from t000 into lv_cccategory where mandt = sy-mandt. if sy-subrc = 0 and lv_cccategory = 'P'. is_production = abap_true. else. clear is_production. endif. endmethod. ENDCLASS. SELECTION-SCREEN: BEGIN OF LINE, COMMENT 1(15) lbl_l00 FOR FIELD pa_ctext, position 20. parameters: pa_ctext type sy-msgv1 VISIBLE LENGTH 30 LOWER CASE default 'AbapcadabrA 2016'. parameters: pa_syntx AS CHECKBOX default abap_true. SELECTION-SCREEN: COMMENT 55(20) lbl_l01 FOR FIELD pa_syntx. SELECTION-SCREEN: END OF LINE. SELECTION-SCREEN: BEGIN OF LINE, COMMENT 1(15) lbl_l02 FOR FIELD pa_sta01. parameters: pa_sta01 type icon_d VISIBLE LENGTH 2 modif ID ico. parameters: pa_src01 type sy-repid OBLIGATORY VISIBLE LENGTH 30. parameters: pa_inf01 type c length 30 modif ID inf. define parameter_line. SELECTION-SCREEN: END OF LINE, BEGIN OF LINE, position 17. parameters: pa_sta&1 type icon_d VISIBLE LENGTH 2 modif ID ico . parameters: pa_src&1 type sy-repid VISIBLE LENGTH 30. parameters: pa_inf&1 type c length 30 modif ID inf. end-of-definition. parameter_line: 02, 03, 04, 05, 06, 07, 08, 09, 10. SELECTION-SCREEN: END OF LINE, SKIP, BEGIN OF LINE, position 17. parameters: pa_sta11 type icon_d VISIBLE LENGTH 2 modif ID ico . parameters: pa_src11 type sy-repid VISIBLE LENGTH 30. parameters: pa_inf11 type c length 30 modif ID inf. parameter_line: 12, 13, 14, 15, 16, 17, 18, 19, 20. SELECTION-SCREEN: END OF LINE. define f4_line. AT SELECTION-SCREEN ON VALUE-REQUEST FOR pa_src&1. lcl_copywriter=>f4_source( EXPORTING parsource = 'PA_SRC&1' ). end-of-definition. f4_line: 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20. AT SELECTION-SCREEN OUTPUT. clear gv_encoding_requests. loop at screen. if screen-group1 = 'ICO'. screen-input = 0. modify screen. endif. if screen-group1 = 'INF'. screen-input = 0. screen-output = 1. * screen-display_3d = 0. modify screen. endif. endloop. * Check all entries: define set_icon. clear: pa_inf&1. if pa_src&1 is initial. pa_sta&1 = '@P7@'. "No source else. if pa_src&1 = sy-repid. pa_sta&1 = '@03@'. pa_inf&1 = 'Source is for current report'. else. select single srtfd from hlpindx into lv_srtfd where relid = 'ZC' and srtfd = pa_src&1 and srtf2 = 0. if sy-subrc = 0. pa_sta&1 = '@06@'. "Source is already in the vault else. select single devclass from tadir into lv_devclass where pgmid = 'R3TR' and object = 'PROG' and obj_name = pa_src&1. if sy-subrc = 0. if lv_devclass(1) co '$YZ'. pa_sta&1 = '@07@'. gv_encoding_requests = abap_true. * The coding could be inactive... select single state from PROGDIR into lv_state where name = pa_src&1 and state = 'I'. if sy-subrc = 0. pa_sta&1 = '@8I@'. pa_inf&1 = 'Source is inactive'. endif. else. pa_sta&1 = '@OJ@'. pa_inf&1 = 'Not a custom coding object'. endif. else. pa_sta&1 = '@02@'. "Devclass for source could not be determined pa_inf&1 = 'Invalid report (not found)'. endif. endif. endif. endif. end-of-definition. set_icon: 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20. define set_info. if pa_sta&1 = '@06@'. "On the vault import info = pa_inf&1 from database HLPINDX(ZC) id pa_src&1. endif. end-of-definition. set_info: 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20. if LCL_copywriter=>is_production_system( ) = abap_true. loop at screen. screen-input = 0. modify screen. endloop. message 'Code locker is NOT for production systems' type 'S'. endif. initialization. lbl_l00 = 'Copyright owner'. lbl_l01 = 'Syntax check'. lbl_l02 = 'Abap sources'. start-of-selection. set_icon: 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20. data: go_copywriter type ref to lcl_copywriter. create object go_copywriter. go_copywriter->gv_copyright_owner = pa_ctext. go_copywriter->gv_syntax_check = pa_syntx. go_copywriter->gv_password = go_copywriter->get_password( 'Enter access code' ). clear go_copywriter->gw_proceslog. if gv_encoding_requests = abap_true. go_copywriter->gv_password2 = go_copywriter->get_password( 'Re-enter access code' ). if go_copywriter->gv_password <> go_copywriter->gv_password2. message 'Passwords do not match' type 'S'. leave program. endif. endif. define process_object. go_copywriter->scramble_or_reinstate( pa_src&1 ). end-of-definition. process_object: 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20. if go_copywriter->gw_proceslog-scrambled_linecount = 0. concatenate go_copywriter->gw_proceslog-original_linecount 'lines restored' into go_copywriter->gw_proceslog-message SEPARATED BY SPACE. else. concatenate go_copywriter->gw_proceslog-original_linecount 'lines processed, ' go_copywriter->gw_proceslog-scrambled_linecount 'lines saved' into go_copywriter->gw_proceslog-message SEPARATED BY SPACE. * concatenate * 'Skipped:' go_copywriter->gw_proceslog-skipped * 'Protected:' go_copywriter->gw_proceslog-scrambled * '+' go_copywriter->gw_proceslog-scrambled_light * '(light) Recovered:' go_copywriter->gw_proceslog-unscrambled * into go_copywriter->gw_proceslog-message SEPARATED BY SPACE. endif. message go_copywriter->gw_proceslog-message type 'S'.