-----------------------------------------------
                     FOXPRO APP FILE STRUCTURE (UNDOCUMENTED)
                                 January 2024
                 -----------------------------------------------
                                    CCB



1. App head structure:

     00000000:  FE F2 FF 20-02 05 00 00-00 85 22 00-00 49 22 00  ................
     00000010:  00 3C 00 00-00 00 00 00-00 00 00 00-00 00 00 00  ................
     00000020:  00 00 00 00-00 00 00 F3-D1                       .........

     00-04 DB fox magic: FE F2 FF 20 02
     05-06 DW number of files: 0x0005
     07-08 DW main file order: 0x0000
     09-0C DD offset of file size description: 0x00002285
     0D-10 DD offset of file name description: 0x00002249
     11-14 DD size of file name description: 0x0000003C
     15-26 DB reserved: 0x12 dup (0x00)
     27-28 DW checksum: 0xD1F3 (reference papp_sum.prg)


2. File name description:

     00002240:                             66 6F 78-2E 70 72 67           fox.prg
     00002250:  00 63 3A 5C-74 65 6D 70-5C 00 66 6F-78 2E 66 78   c:\temp\ fox.fx
     00002260:  70 00 2E 5C-00 66 6F 78-2E 73 63 78-00 66 6F 78  p .\ fox.scx fox
     00002270:  2E 73 63 74-00 66 6F 78-2E 66 72 78-00 66 6F 78  .sct fox.frx fox
     00002280:  2E 66 72 74-00                                   .frt

     Relative file name description:

     00000000:  66 6F 78 2E-70 72 67 00-63 3A 5C 74-65 6D 70 5C  fox.prg c:\temp\
     00000010:  00 66 6F 78-2E 66 78 70-00 2E 5C 00-66 6F 78 2E   fox.fxp .\ fox.
     00000020:  73 63 78 00-66 6F 78 2E-73 63 74 00-66 6F 78 2E  scx fox.sct fox.
     00000030:  66 72 78 00-66 6F 78 2E-66 72 74 00              frx fox.frt

     00-07 DB "fox.prg",0
     08-10 DB "c:\temp\",0
     11-18 DB "fox.fxp",0
     19-1B DB ".\",0
     1C-23 DB "fox.scx",0
     24-2B DB "fox.sct",0
     2C-33 DB "fox.frx",0
     34-3B DB "fox.frt",0


3. File type:

     00: program file, include program file .PRG/.FXP, format file .FMT/.PRX, 
         screen file .SPR/.SPX, menu file .MPR/.MPX, query file .QPR/.QPX
     02: table file, include database file .DBC, table file .DBF
     03: memo file, include memo file .FPT, class memo file .VCT, form memo file .SCT,
         report memo file .FRT, label memo file .LBT
     04: compound index file .CDX
     05: compact index file .IDX
     06: text file .TXT
     07: api library file .FLL
     08: class file .VCX
     09: form file .SCX
     0A: report file .FRX
     0B: label file .LBX


4. File size description:

     Total 5 files:

     00002280:                 00 29 00-00 00 47 01-00 00 08 00  ................
     00002290:  00 00 11 00-00 00 00 00-00 00 00 00-00 00 09 47  ................
     000022A0:  01 00 00 04-07 00 00 19-00 00 00 1C-00 00 00 00  ................
     000022B0:  00 00 00 00-00 00 00 03-04 07 00 00-5C 0A 00 00  ................
     000022C0:  19 00 00 00-24 00 00 00-00 00 00 00-00 00 00 00  ................
     000022D0:  0A 5C 0A 00-00 43 1A 00-00 19 00 00-00 2C 00 00  ................
     000022E0:  00 00 00 00-00 00 00 00-00 03 43 1A-00 00 49 22  ................
     000022F0:  00 00 19 00-00 00 34 00-00 00 00 00-00 00 00 00  ................
     00002300:  00 00                                            ..

     1) fox.fxp:
   
     00002280:                 00 29 00-00 00 47 01-00 00 08 00       ...........
     00002290:  00 00 11 00-00 00 00 00-00 00 00 00-00 00        ..............

     00-00 DB file type: 0x00 (program file)
     01-04 DD start offset of file: 0x00000029
     05-08 DD end offset of file: 0x00000147
     09-0C DD offset of file path: 0x00000008 (relative file name description) -> "c:\temp\",0
     0D-10 DD offset of file name: 0x00000011 (relative file name description) -> "fox.fxp",0
     11-14 DD reserved: 0x00000000
     15-18 DD reserved: 0x00000000

     00000020:                             02 00 01-00 25 00 00           .......
     00000030:  00 7E 00 00-00 AF 00 00-00 DE 00 00-00 0B 00 00  ................
     00000040:  00 C8 00 00-00 5C 56 83-3A 00 00 00-00 85 16 00  ................
     00000050:  0F 00 02 F8-03 01 FC D9-03 00 66 6F-78 FD FE 04  ..........fox...
     00000060:  00 52 FE 03-00 55 00 00-17 00 10 00-54 F7 00 00  ................
     00000070:  10 FC D9 03-00 66 6F 78-FD FE 04 00-52 FE 03 00  .....fox........
     00000080:  55 01 00 02-00 58 31 18-00 11 00 54-F7 00 00 10  .....X1.........
     00000090:  FC D9 04 00-66 6F 78 32-FD FE 04 00-52 FE 03 00  ....fox2........
     000000A0:  55 01 00 02-00 58 32 08-00 70 72 6F-63 5F 66 6F  .....X2..proc_fo
     000000B0:  78 3F 00 00-00 00 00 FF-FF 04 00 49-4E 49 54 5E  x..........INIT.
     000000C0:  00 00 00 01-00 00 00 0D-00 0A 00 A2-E9 00 02 00  ................
     000000D0:  00 00 FE 03-00 55 00 00-09 00 63 6C-61 73 73 5F  ..........class_
     000000E0:  66 6F 78 06-00 43 55 53-54 4F 4D 9E-00 00 00 00  fox..CUSTOM......
     000000F0:  00 F1 00 41-00 31 00 41-01 41 00 32-00 51 01 41  ................
     00000100:  00 31 00 A1-00 33 00 00-00 00 00 00-00 00 00 00  ................
     00000110:  00 00 00 00-00 00 00 03-00 00 00 1D-00 00 00 2E  ................
     00000120:  00 00 00 03-00 00 00 06-00 00 00 5D-00 00 00 6F  ................
     00000130:  00 00 00 07-00 00 00 09-00 00 00 52-00 00 00 6F  ................
     00000140:  00 00 00 06-00 00 00                             .......

     2) fox.scx:

     00002290:                                            09 47                ..
     000022A0:  01 00 00 04-07 00 00 19-00 00 00 1C-00 00 00 00  ................
     000022B0:  00 00 00 00-00 00 00                             .......

     00-00 DB file type: 0x09 (form file)
     01-04 DD start offset of file: 0x00000147
     05-08 DD end offset of file: 0x00000704
     09-0C DD offset of file path: 0x00000019 (relative file name description) -> ".\",0
     0D-10 DD offset of file name: 0x0000001C (relative file name description) -> "fox.scx",0
     11-14 DD reserved: 0x00000000
     15-18 DD reserved: 0x00000000

     00000140:                       30-09 04 03 04-00 00 00 08        0.........
     00000150:  04 6D 00 00-00 00 00 00-00 00 00 00-00 00 00 00  ................
     00000160:  00 00 00 02-7A 00 00 50-4C 41 54 46-4F 52 4D 00  .......PLATFORM.
     00000170:  00 00 43 01-00 00 00 08-00 00 00 00-00 00 00 00  ..C.............
     00000180:  00 00 00 00-00 00 00 55-4E 49 51 55-45 49 44 00  .......UNIQUEID.
     00000190:  00 00 43 09-00 00 00 0A-00 00 00 00-00 00 00 00  ..C.............
     000001A0:  00 00 00 00-00 00 00 54-49 4D 45 53-54 41 4D 50  .......TIMESTAMP
     000001B0:  00 00 4E 13-00 00 00 0A-00 00 00 00-00 00 00 00  ..N.............
     ............................................................................
     000006E0:  00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00  ................
     000006F0:  00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00  ................
     00000700:  00 00 00 1A                                      ....

     3) fox.sct:

     000022B0:                       03-04 07 00 00-5C 0A 00 00  ................
     000022C0:  19 00 00 00-24 00 00 00-00 00 00 00-00 00 00 00  ................

     00-00 DB file type: 0x03 (memo file)
     01-04 DD start offset of file: 0x00000704
     05-08 DD end offset of file: 0x00000A5C
     09-0C DD offset of file path: 0x00000019 (relative file name description) -> ".\",0
     0D-10 DD offset of file name: 0x00000024 (relative file name description) -> "fox.sct",0
     11-14 DD reserved: 0x00000000
     15-18 DD reserved: 0x00000000

     00000700:              00 00 03 58-00 00 00 01-00 00 00 00      ............
     00000710:  00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00  ................
     00000720:  00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00  ................
     ............................................................................
     00000A00:  33 44 6F 43-72 65 61 74-65 20 3D 20-2E 54 2E 0D  3DoCreate = .T..
     00000A10:  0A 43 61 70-74 69 6F 6E-20 3D 20 22-46 6F 72 6D  .Caption = "Form
     00000A20:  31 22 0D 0A-4E 61 6D 65-20 3D 20 22-46 6F 72 6D  1"..Name = "Form
     00000A30:  31 22 0D 0A-00 00 00 01-00 00 00 20-CB CE CC E5  1"..............
     00000A40:  2C 20 30 2C-20 39 2C 20-36 2C 20 31-34 2C 20 31  , 0, 9, 6, 14, 1
     00000A50:  30 2C 20 31-32 2C 20 32-2C 20 32 0A              0, 12, 2, 2.

     4) fox.frx:

     000022D0:  0A 5C 0A 00-00 43 1A 00-00 19 00 00-00 2C 00 00  ................
     000022E0:  00 00 00 00-00 00 00 00-00                       .........

     00-00 DB file type: 0x0A (report file)
     01-04 DD start offset of file: 0x00000A5C
     05-08 DD end offset of file: 0x00001A43
     09-0C DD offset of file path: 0x00000019 (relative file name description) -> ".\",0
     0D-10 DD offset of file name: 0x0000002C (relative file name description) -> "fox.frx",0
     11-14 DD reserved: 0x00000000
     15-18 DD reserved: 0x00000000

     00000A50:                                      30 09 04 03  ............0...
     00000A60:  06 00 00 00-88 0A E5 00-00 00 00 00-00 00 00 00  ................
     00000A70:  00 00 00 00-00 00 00 00-02 7A 00 00-50 4C 41 54  ............PLAT
     00000A80:  46 4F 52 4D-00 00 00 43-01 00 00 00-08 00 00 00  FORM...C........
     00000A90:  00 00 00 00-00 00 00 00-00 00 00 00-55 4E 49 51  ............UNIQ
     00000AA0:  55 45 49 44-00 00 00 43-09 00 00 00-0A 00 00 00  UEID...C........
     00000AB0:  00 00 00 00-00 00 00 00-00 00 00 00-54 49 4D 45  ............TIME
     00000AC0:  53 54 41 4D-50 00 00 4E-13 00 00 00-0A 00 00 00  STAMP..N........
     ............................................................................
     00001A20:  20 20 20 20-20 20 20 20-20 20 20 20-20 20 20 20  ................
     00001A30:  20 20 20 20-20 20 20 20-20 20 00 00-00 00 00 00  ................
     00001A40:  00 00 1A                                         ...

     5) fox.frt:

     000022E0:                             03 43 1A-00 00 49 22  ................
     000022F0:  00 00 19 00-00 00 34 00-00 00 00 00-00 00 00 00  ................
     00002300:  00 00                                            ..

     00-00 DB file type: 0x03 (memo file)
     01-04 DD start offset of file: 0x00001A43
     05-08 DD end offset of file: 0x00002249
     09-0C DD offset of file path: 0x00000019 (relative file name description) -> ".\",0
     0D-10 DD offset of file name: 0x00000034 (relative file name description) -> "fox.frt",0
     11-14 DD reserved: 0x00000000
     15-18 DD reserved: 0x00000000

     00001A40:           00-00 00 3E 00-00 00 21 00-00 00 00 00     .............
     00001A50:  00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00  ................
     00001A60:  00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00  ................
     ............................................................................
     00002200:  20 30 0D 0A-48 65 69 67-68 74 20 3D-20 30 0D 0A   0..Height = 0..
     00002210:  44 61 74 61-53 6F 75 72-63 65 20 3D-20 2E 4E 55  DataSource = .NU
     00002220:  4C 4C 2E 0D-0A 4E 61 6D-65 20 3D 20-22 44 61 74  LL...Name = "Dat
     00002230:  61 65 6E 76-69 72 6F 6E-6D 65 6E 74-22 0D 0A 00  aenvironment"...
     00002240:  00 00 00 00-01 00 00 00-00                       .........


5. Fxp head structure:

     00000020:                             02 00 01-00 25 00 00           .......
     00000030:  00 7E 00 00-00 AF 00 00-00 DE 00 00-00 0B 00 00  ................
     00000040:  00 C8 00 00-00 5C 56 83-3A 00 00 00-00 85        ..............

     Relative fxp head:

     00000000:  02 00 01 00-25 00 00 00-7E 00 00 00-AF 00 00 00  ................
     00000010:  DE 00 00 00-0B 00 00 00-C8 00 00 00-5C 56 83-3A  ................
     00000020:  00 00 00 00-85                                   .....

     00-01 DW number of procedures: 0x0002
     02-03 DW number of classes: 0x0001
     04-07 DD start offset of fxp file: 0x00000025
     08-0B DD offset of procedure name description: 0x0000007E
     0C-0F DD offset of class name description: 0x000000AF
     10-13 DD offset of procedures/classes description (debug info): 0x000000DE
     14-17 DD lines (debug info): 0x0000000B
     18-1B DD offset of lineno description (debug info): 0x000000C8
     1C-1F DD timestamp: 0x3A833F57 = 2009/04/03 07:58:46 (reference ftimestamp2datetime.prg)
     20-23 DD offset of the source file name (relative file name description)
     24-24 DB codepage: 0x85(936GBK), 0x87(950BIG5)


6. Procedure name description:

     0) fox.fxp:

     00000020:                 16 00 0F-00 02 F8 03-01 FC D9 03       ...........
     00000030:  00 66 6F 78-FD FE 04 00-52 FE 03 00-55 00 00     .fox...........

     25-26: size of procedure: 0x0016
     27-28: size of first line p-code: 0x000F
     29-35: first line p-code: ?"fox"
     36-37: size of 2nd line p-code: 0x0004
     38-39: 2nd line p-code: WAIT
     3A-3B: size of 3th line p-code: 0x0003
     3C-3C: 3th line p-code: END

     3D-3E: number of names (variable etc.): 0x0000

     Total 2 procedures:

     00000070:                                            08 00                ..
     00000080:  70 72 6F 63-5F 66 6F 78-3F 00 00 00-00 00 FF FF  proc_fox........
     00000090:  04 00 49 4E-49 54 5E 00-00 00 01 00-00 00        ..INIT........

     1) procedure proc_fox:

     00000070:                                            08 00                ..
     00000080:  70 72 6F 63-5F 66 6F 78-3F 00 00 00-00 00 FF FF  proc_fox........

     00------01     DW size of procedure name=N
     02------02+N-1 DB procedure name: "proc_fox"
     02+N----02+N+3 DD start offset of procedure (relative fxp head): 0x0000003F
     02+N+4--02+N+5 DW class flag: 0x0000
     02+N+6--02+N+7 DW class order: 0xFFFF

     00000030:                                               17  .fox............
     00000040:  00 10 00 54-F7 00 00 10-FC D9 03 00-66 6F 78 FD  ............fox.
     00000050:  FE 04 00 52-FE 03 00 55-01 00 02 00-58 31        ............X1

     3F-40: size of procedure: 0x0017
     41-42: size of first line p-code: 0x0010
     43-50: first line p-code: X1="fox"
     51-52: size of 2nd line p-code: 0x0004
     53-54: 2nd line p-code: WAIT
     55-56: size of 3th line p-code: 0x0003
     57-57: 3th line p-code: END

     58-59: number of names (variable etc.): 0x0001
     5A-5B: size of first name (variable etc.): 0x0002
     5C-5D: first name (variable etc.): "X1"

     2) procedure INIT:

     00000090:  04 00 49 4E-49 54 5E 00-00 00 01 00-00 00        ..INIT........

     00------01     DW size of procedure name=N
     02------02+N-1 DB procedure name: "INIT"
     02+N----02+N+3 DD start offset of procedure name (relative fxp head): 0x0000005E
     02+N+4--02+N+5 DW class flag: 0x0001
     02+N+6--02+N+7 DW class order: 0x0000

     00000050:                                            18 00  ................
     00000060:  11 00 54 F7-00 00 10 FC-D9 04 00 66-6F 78 32 FD  ................
     00000070:  FE 04 00 52-FE 03 00 55-01 00 02 00-58 32        ............X2

     5E-5F: size of procedure: 0x0018
     60-61: size of first line p-code: 0x0011
     62-70: first line p-code: X2="fox2"
     71-72: size of 2nd line p-code: 0x0004
     73-74: 2nd line p-code: WAIT
     75-76: size of 3th line p-code: 0x0003
     77-77: 3th line p-code: END

     78-79: number of names (variable etc.): 0x0001
     7A-7B: size of first name (variable etc.): 0x0002
     7C-7D: first name (variable etc.): "X2"

     3) vfp9 procedure size >64K format

     Before vfp9, procedure size <64K, use one WORD can save the size of procedure:
     00-01 DW size of procedure

     In vfp9, procedure size >64K possible, use one WORD and one DWORD to save the size of procedure:
     00-01 DW 0
     02-05 DD size of procedure


7. Class name description:

     Total 1 class:

     000000A0:                                               09                 .
     000000B0:  00 63 6C 61-73 73 5F 66-6F 78 06 00-43 55 53 54  .class_fox..CUST
     000000C0:  4F 4D 9E 00-00 00 00 00                          OM.......

     00-----------01          DW size of class name=N
     02-----------02+N-1      DB class name: "class_fox"
     02+N---------02+N+01     DW size of parent class name=M
     02+N+02------02+N+02+M-1 DB parent class name: "CUSTOM"
     02+N+02+M----02+N+02+M+3 DD start offset of class (relative fxp head): 0x0000009E
     02+N+02+M+4--02+N+02+M+5 DW reserved: 0x0000

     00000090:                                            0D 00                ..
     000000A0:  0A 00 A2 E9-00 02 00 00-00 FE 03 00-55 00 00     ...............

     9E-9F: size of procedure: 0x000D
     A0-A1: size of first line p-code: 0x000A
     A2-A9: first line p-code: DEFINE CLASS class_fox AS CUSTOM
     AA-AB: size of 2nd line p-code: 0x0003
     AC-AC: 2nd line p-code: END

     AD-AE: number of names (variable etc.): 0x0000


8. Lineno description (debug info):

     Total 0x0000000B WORDs, one WORD for per lines.

     000000C0:                          F1 00 41 00-31 00 01 01          ........
     000000D0:  41 00 32 00-11 01 41 00-31 00 A1 00-33 00        ..............


9. Procedures/classes description (debug info):

     Total (1+2+1)*4 DWORDs, four DWORDs for per fxp, procedures, classes.

     000000D0:                                            00 00                ..
     000000E0:  00 00 00 00-00 00 00 00-00 00 00 00-00 00 03 00  ................
     000000F0:  00 00 1D 00-00 00 2B 00-00 00 03 00-00 00 06 00  ................
     00000100:  00 00 5A 00-00 00 69 00-00 00 07 00-00 00 09 00  ................
     00000110:  00 00 4F 00-00 00 69 00-00 00 06 00-00 00        ..............


10. Summary of fox.app:

     0000-0028 app head
     0029-004D fxp head
     004E-0067 fox.fxp
     0068-0086 procedure proc_fox
     0087-00A6 procedure INIT
     00A7-00C6 procedure name description
     00C7-00D7 DEFINE CLASS class_fox AS CUSTOM
     00D8-00F0 class name description
     00F1-0106 lineno description (debug info)
     0107-0146 procedures/classes description (debug info)
     0147-0703 fox.scx
     0704-0A5B fox.sct
     0A5C-1A42 fox.frx
     1A43-2248 fox.frt
     2249-2284 file name description
     2285-2301 file size description

     This is a STANDARD-FORMAT app file.

     To make a non-STANDARD-FORMAT app file,
     we can change the order of the parts and/or insert some un-used data into parts,
     then the app file can run, but it can not be decompiled with some decompile software.


11. Reference 1: papp_sum.prg

     *PROC papp_sum

     PARAMETER m.q_str

     * m.q_str =

     * PARAMETER: String
     * RETURN: Checksum

     PRIVATE m.q_nn
     PRIVATE m.q_sum
     PRIVATE m.q_suma
     PRIVATE m.q_suma1
     PRIVATE m.q_suma2
     PRIVATE m.q_sumb
     PRIVATE m.q_sumb1
     PRIVATE m.q_sumb2
     PRIVATE m.q_sumc
     PRIVATE m.q_sumc1
     PRIVATE m.q_sumc2
     PRIVATE m.q_sumd
     PRIVATE m.q_sumd1
     PRIVATE m.q_sumd2
     PRIVATE m.q_sume
     PRIVATE m.q_sumf

     *
     * FoxPro Application File (.APP) Checksum
     * 1998.05.01 Write by CCB
     *
     * Crack with Soft-ice
     *
     * ASM CODE:
     *
     * code    segment
     *
     *         assume  cs:code,ds:code,es:code
     *
     *         org     100h
     *
     * start:
     *
     *         jmp     begin
     *
     * head_25         db 0feh,0f2h,0ffh,0ffh,0ch,02h
     * head_30         db 0feh,0f2h,0ffh,1bh,02h
     * head_50         db 0feh,0f2h,0ffh,1fh,02h
     *
     * head            db 0feh,0f2h,0ffh,0ffh,0ch,02h
     *                 dw 00a0h
     *                 dw 0001h
     *                 dd 1430h
     *                 dd 0430h
     *                 dd 1000h
     *                 db 18 dup(0)
     * head_len        = $ - (offset head)
     * head_sum        dw ?          ; 71f6h / 8d11h / ddc7h
     *
     * begin:
     *
     *         push    cs
     *         pop     ds
     *
     *         mov     ah,byte ptr head[0]
     *         mov     al,byte ptr head[1]
     *
     *         mov     si,0
     *
     *         mov     bx,head_len-2
     *
     * s_loop:
     *
     *         cmp     bx,0
     *         jz      s_save
     *
     *         mov     dl,ah
     *         mov     dh,al
     *         mov     al,byte ptr head[si]
     *         xor     ah,ah
     *         xor     ax,dx
     *         mov     dx,ax
     *         mov     cl,4
     *         xor     dh,ah
     *         shr     dx,cl
     *         xor     ax,dx
     *         mov     dx,ax
     *         xor     dh,ah
     *         xor     cl,cl
     *         mov     ch,al
     *         mov     di,0
     *         add     di,cx
     *         mov     cl,4
     *         shl     di,cl
     *         mov     cl,5
     *         xor     ax,di
     *         shl     dx,cl
     *         xor     ax,dx
     *         inc     si
     *         dec     bx
     *         jmp     s_loop
     *
     * s_save:
     *
     *         mov     head_sum,ax
     *
     *         mov     ax,4c00h
     *         int     21h
     *
     * code    ends
     *
     *         end     start
     *
     *
     *               AX             head[si]
     *       -----------------     ---------
     *       | a | b | c | d |     | e | f |
     *       -----------------     ---------
     *
     *               AX                    DX
     *       ------------------    -----------------
     *       | c | d | a | a |     | 0 | a | a | 0 |
     *       | a |   | e | b |     |   | e | b |   |
     *       | b |   |   | e |     |   |   | e |   |
     *       | e |   |   | f |     |   |   | f |   |
     *       | f |   |   |   |     |   |   |   |   |
     *       --|-------|---|---    ------|---|------
     *        XOR     XOR XOR           XOR XOR
     *
     *       (AX) = (AX) XOR (DX)*2
     *
     * FOXPRO CODE:
     *

     m.q_sum=ASC(SUBS(m.q_str,1,1))*256+ASC(SUBS(m.q_str,2,1))
     m.q_suma=INT(MOD(m.q_sum,16^4)/16^3)
     m.q_sumb=INT(MOD(m.q_sum,16^3)/16^2)
     m.q_sumc=INT(MOD(m.q_sum,16^2)/16^1)
     m.q_sumd=INT(MOD(m.q_sum,16^1)/16^0)

     m.q_nn=1

     DO WHILE m.q_nn<=LEN(m.q_str)-2

        m.q_sum=ASC(SUBS(m.q_str,m.q_nn,1))
        m.q_sume=INT(MOD(m.q_sum,16^2)/16^1)
        m.q_sumf=INT(MOD(m.q_sum,16^1)/16^0)

        m.q_suma2=0
        m.q_sumb2=fbin_xor(m.q_suma,m.q_sume)
        m.q_sumc2=fbin_xor(fbin_xor(fbin_xor(m.q_suma,m.q_sumb),m.q_sume),m.q_sumf)
        m.q_sumd2=0

        m.q_sum=m.q_suma2*16^3+m.q_sumb2*16^2+m.q_sumc2*16^1+m.q_sumd2*16^0
        m.q_sum=m.q_sum*2
        m.q_suma2=INT(MOD(m.q_sum,16^4)/16^3)
        m.q_sumb2=INT(MOD(m.q_sum,16^3)/16^2)
        m.q_sumc2=INT(MOD(m.q_sum,16^2)/16^1)
        m.q_sumd2=INT(MOD(m.q_sum,16^1)/16^0)

        m.q_suma1=fbin_xor(fbin_xor(fbin_xor(fbin_xor(m.q_sumc,m.q_suma),m.q_sumb),m.q_sume),m.q_sumf)
        m.q_sumb1=m.q_sumd
        m.q_sumc1=fbin_xor(m.q_suma,m.q_sume)
        m.q_sumd1=fbin_xor(fbin_xor(fbin_xor(m.q_suma,m.q_sumb),m.q_sume),m.q_sumf)

        m.q_suma=fbin_xor(m.q_suma1,m.q_suma2)
        m.q_sumb=fbin_xor(m.q_sumb1,m.q_sumb2)
        m.q_sumc=fbin_xor(m.q_sumc1,m.q_sumc2)
        m.q_sumd=fbin_xor(m.q_sumd1,m.q_sumd2)

        m.q_nn=m.q_nn+1

     ENDDO

     RETU CHR(m.q_sumc*16+m.q_sumd)+CHR(m.q_suma*16+m.q_sumb)

     FUNCTION fbin_xor

     PARAMETER m.q_a,m.q_b

     * m.q_a =
     * m.q_b =

     RETU IIF(INT(MOD(m.q_a,16)/8)#INT(MOD(m.q_b,16)/8),1,0)*8+;
        IIF(INT(MOD(m.q_a,8)/4)#INT(MOD(m.q_b,8)/4),1,0)*4+;
        IIF(INT(MOD(m.q_a,4)/2)#INT(MOD(m.q_b,4)/2),1,0)*2+;
        IIF(INT(MOD(m.q_a,2)/1)#INT(MOD(m.q_b,2)/1),1,0)*1

     * END OF FUNCTION FBIN_XOR.

     * END OF PROC PAPP_SUM.


12. Reference 2: ftimestamp2datetime.prg

     *PROC ftimestamp2datetime

     PARAMETER m.q_timestamp

     * m.q_timestamp =

     * PARAMETER: TIMESTAMP
     * RETURN: Datetime

     IF TYPE("m.q_timestamp")#"N"
        m.q_timestamp=0
     ENDI

     m.q_timestamp=ABS(INT(m.q_timestamp))

     PRIVATE m.q_year
     m.q_year=1980+INT(m.q_timestamp/2^25)  && bits 31-25

     PRIVATE m.q_month
     m.q_month=INT(MOD(m.q_timestamp,2^25)/2^21)  && bits 24-21

     PRIVATE m.q_day
     m.q_day=INT(MOD(m.q_timestamp,2^21)/2^16)  && bits 20-16

     PRIVATE m.q_hour
     m.q_hour=INT(MOD(m.q_timestamp,2^16)/2^11)  && bits 15-11

     PRIVATE m.q_minute
     m.q_minute=INT(MOD(m.q_timestamp,2^11)/2^5)  && bits 10-5

     PRIVATE m.q_second
     m.q_second=INT(MOD(m.q_timestamp,2^5)/2^0)*2  && bits 4-0 (two-second increments)

     IF m.q_year<1
        m.q_year=1
     ENDI
     IF m.q_year>9999
        m.q_year=9999
     ENDI

     IF m.q_month<1
        m.q_month=1
     ENDI
     IF m.q_month>12
        m.q_month=12
     ENDI

     PRIVATE m.q_daymin
     m.q_daymin=1

     PRIVATE m.q_daymax
     m.q_daymax=DAY(GOMONTH(DATE(m.q_year,m.q_month,1),+1)-1)

     IF m.q_day< m.q_daymin
        m.q_day=m.q_daymin
     ENDI
     IF m.q_day>m.q_daymax
        m.q_day=m.q_daymax
     ENDI

     IF m.q_hour<0
        m.q_hour=0
     ENDI
     IF m.q_hour>23
        m.q_hour=23
     ENDI

     IF m.q_minute<0
        m.q_minute=0
     ENDI
     IF m.q_minute>59
        m.q_minute=59
     ENDI

     IF m.q_second<0
        m.q_second=0
     ENDI
     IF m.q_second>59
        m.q_second=59
     ENDI

     RETU datetime(m.q_year,m.q_month,m.q_day,m.q_hour,m.q_minute,m.q_second)

     * END OF PROC FTIMESTAMP2DATETIME.


13. Other

     For reference only, there is no guarantees.

     Any questions or suggestions, please send me an email at ccb2000@163.com.