---------------------------------------------------------- [BUG/PRB.] VFP 9.0 FIX - REPORT FOOTER January 2024 ---------------------------------------------------------- CCB 1. BUG: There is a report for test: Paper: A4 (21.0cm x 29.7cm) Print area: Whole page Page Header: Height = 5.0cm Detail: Height = 2.0cm Page Footer: Height = 4.7cm or 4.65cm The report prints 10 records per page: 29.7cm = 5.0cm + 2.0cm x 10 + 4.7cm Please refer to the picture testreport.jpg: In vfp8, the report is correct for all printers. Please refer to the picture testreport8.jpg: But in vfp9, there are some blank spaces between the detail and the page footer. Please refer to the picture testreport9.jpg: 2. CAUSE: We can calculate the top non-printable area for different printer: GetDeviceCaps(hdc,PHYSICALOFFSETY) / GetDeviceCaps(hdc,LOGPIXELSY) x 2.54 For Epson LQ-1600K, the value is 0.846667cm. For HP LaserJet 1020, the value is 0.397933cm. For Adobe PDF, the value is 0cm. This value is equal to the height of the blank spaces. The BUG is the top non-printable area has been added to the page footer. 3. RESOLUTION: We can write some code to fix the BUG. 1, Please refer to the file vfp9fix.h: //+-------------------------------------------------------------------------- // // File: pro_ext.h // // Copyright: (c) 1999, Microsoft Corporation. // All Rights Reserved. // Information Contained Herein is Proprietary // and Confidential. // // Contents: API Header for the Library Construction Kit // // Notes: // //--------------------------------------------------------------------------- #ifndef PRO_EXT_INCLUDED #define PRO_EXT_INCLUDED #if defined(_MSC_VER) #pragma pack(push, 1) // Assume byte structure packing #endif #ifdef __cplusplus extern "C" { // Assume C declarations for C++ #endif // Fastcall calling convention #define FASTCALL _fastcall // FPFI is a 32 bit pointer to a function returning an int typedef long (*FPFI)(); // The FoxInfo structure contains the descriptions of the functions // contained in the library. typedef struct { char * funcName; /* Function name (all caps) */ FPFI function; /* Actual function address */ short parmCount; /* # parameters specified or a flag value */ char * parmTypes; /* Parameter list description */ } FoxInfo; typedef struct _FoxTable { struct _FoxTable *nextLibrary; /* Linked list of libraries */ short infoCount; /* # of functions in this library */ FoxInfo *infoPtr; /* Function list */ } FoxTable; // An expression's value typedef struct { char ev_type; char ev_padding; short ev_width; unsigned ev_length; long ev_long; double ev_real; long ev_currency; long ev_currency2; unsigned ev_handle; unsigned long ev_object; } Value; // A reference to a database or memory variable typedef struct { char l_type; short l_where, /* Database number or -1 for memory */ l_NTI, /* Variable name table offset */ l_offset, /* Index into database */ l_subs, /* # subscripts specified 0 <= x <= 2 */ l_sub1, l_sub2; /* subscript integral values */ } Locator; typedef union { Value val; Locator loc; /* An 'R' in l_type means the Locator */ /* part of this union is in use. */ } FoxParameter; // A paramter list to a library function. typedef struct { short pCount; /* Number of Parameters PASSED. */ FoxParameter p[1]; /* pCount Parameters. */ } ParamBlk; int FASTCALL _Execute(char *stmt); int FASTCALL _Evaluate(Value *val, char *expr); void FASTCALL _Error(int code); void FASTCALL _RetVal(Value *val); int FASTCALL _Store(Locator *loc, Value *val); int FASTCALL _Load(Locator *loc, Value *val); int FASTCALL _FindVar(int nti, int where, Locator *loc); int FASTCALL _NameTableIndex(char *name); #ifdef __cplusplus } // End of extern "C" { #endif #if defined(_MSC_VER) #pragma pack(pop) // Restore structure packing #endif #endif // PRO_EXT_INCLUDED 2, Please refer to the file vfp9fix.c: #include "vfp9fix.h" int __stdcall VirtualProtect(void *lpAddress, int dwSize, int flNewProtect, int *lpflOldProtect); void VFP9FixReportFooter() { Value hmodule0retvalue; unsigned int hmodule0; unsigned int i; unsigned char *p1; unsigned char *p2; unsigned int OldProtect; _Execute("DECLARE integer GetModuleHandle IN win32api string lpfilename"); _Evaluate(&hmodule0retvalue,"GetModuleHandle(_vfp.fullname)"); hmodule0=hmodule0retvalue.ev_long; for (i=0x080000;i<0x100000;i++) { p1=hmodule0+i; if (*(p1+0x09)==0x8B && *(p1+0x0A)==0x50 && *(p1+0x0B)==0x0C && *(p1+0x0C)==0x2B && *(p1+0x0D)==0x56 && *(p1+0x0E)==0x68 && *(p1+0x0F)==0x03 && *(p1+0x10)==0x56 && *(p1+0x11)==0x58) { // fix vfp9.exe, vfp9r.dll // 00498A70 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10] // 00498A73 8078 15 00 CMP BYTE PTR DS:[EAX+15],0 // 00498A77 75 1A JNZ SHORT VFP9.00498A93 // 00498A79 8B50 0C MOV EDX,DWORD PTR DS:[EAX+C] // 00498A7C 2B56 68 SUB EDX,DWORD PTR DS:[ESI+68] // 00498A7F 0356 58 ADD EDX,DWORD PTR DS:[ESI+58] // 00498A82 E8 58BBFFFF CALL VFP9.004945DF // 00498A87 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10] // 00498A8A 8B4E 68 MOV ECX,DWORD PTR DS:[ESI+68] // 00498A8D 2B48 0C SUB ECX,DWORD PTR DS:[EAX+C] // 00498A90 894E 58 MOV DWORD PTR DS:[ESI+58],ECX // fix to: // 00498A70 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10] // 00498A73 50 PUSH EAX // 00498A74 BF 14010000 MOV EDI,114 // 00498A79 8B50 0C MOV EDX,DWORD PTR DS:[EAX+C] // 00498A7C 2B56 68 SUB EDX,DWORD PTR DS:[ESI+68] // 00498A7F 0356 58 ADD EDX,DWORD PTR DS:[ESI+58] // 00498A82 E8 58BBFFFF CALL VFP9.004945DF // 00498A87 33FF XOR EDI,EDI // 00498A89 58 POP EAX // 00498A8A 8B4E 68 MOV ECX,DWORD PTR DS:[ESI+68] // 00498A8D 2B48 0C SUB ECX,DWORD PTR DS:[EAX+C] // 00498A90 894E 58 MOV DWORD PTR DS:[ESI+58],ECX for (i=0x080000;i<0x100000;i++) { p2=hmodule0+i; if (*(p2+0x0E)==0x05 && *(p2+0x0F)==0x14 && *(p2+0x10)==0x01 && *(p2+0x11)==0x00 && *(p2+0x12)==0x00 && *(p2+0x13)==0x29 && *(p2+0x14)==0x50 && *(p2+0x15)==0xF8 && *(p2+0x16)==0x29 && *(p2+0x17)==0x10) { // fix vfp9.exe, vfp9r.dll // 004945DF 8B48 20 MOV ECX,DWORD PTR DS:[EAX+20] // 004945E2 85C9 TEST ECX,ECX // 004945E4 74 19 JE SHORT VFP9.004945FF // 004945E6 8B40 24 MOV EAX,DWORD PTR DS:[EAX+24] // 004945E9 8B00 MOV EAX,DWORD PTR DS:[EAX] // 004945EB 7E 12 JLE SHORT VFP9.004945FF // 004945ED 05 14010000 ADD EAX,114 // 004945F2 2950 F8 SUB DWORD PTR DS:[EAX-8],EDX // 004945F5 2910 SUB DWORD PTR DS:[EAX],EDX // 004945F7 05 4C010000 ADD EAX,14C // 004945FC 49 DEC ECX // 004945FD 75 F3 JNZ SHORT VFP9.004945F2 // 004945FF C3 RETN // fix to: // 004945DF 807C3E CC 00 CMP BYTE PTR DS:[ESI+EDI-34],0 // 004945E4 74 03 JE SHORT VFP9.004945E9 // 004945E6 03143E ADD EDX,DWORD PTR DS:[ESI+EDI] // 004945E9 8B48 20 MOV ECX,DWORD PTR DS:[EAX+20] // 004945EC E3 11 JECXZ SHORT VFP9.004945FF // 004945EE 8B40 24 MOV EAX,DWORD PTR DS:[EAX+24] // 004945F1 8B00 MOV EAX,DWORD PTR DS:[EAX] // 004945F3 03C7 ADD EAX,EDI // 004945F5 2950 F8 SUB DWORD PTR DS:[EAX-8],EDX // 004945F8 2910 SUB DWORD PTR DS:[EAX],EDX // 004945FA 83C0 38 ADD EAX,38 // 004945FD E2 F4 LOOPD SHORT VFP9.004945F3 // 004945FF C3 RETN // _Execute("_SCREEN.VISIBLE=.T."); // _Execute("WAIT WIND 'VFP9FixReportFooter OK.'"); OldProtect=0x20; // PAGE_EXECUTE_READ VirtualProtect(p1,0x20,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE *(p1+0x03)=0x50; *(p1+0x04)=0xBF; *(p1+0x05)=0x14; *(p1+0x06)=0x01; *(p1+0x07)=0x00; *(p1+0x08)=0x00; *(p1+0x17)=0x33; *(p1+0x18)=0xFF; *(p1+0x19)=0x58; VirtualProtect(p1,0x20,OldProtect,&OldProtect); OldProtect=0x20; // PAGE_EXECUTE_READ VirtualProtect(p2,0x20,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE *(p2+0x00)=0x80; *(p2+0x01)=0x7C; *(p2+0x02)=0x3E; *(p2+0x03)=0xCC; *(p2+0x04)=0x00; *(p2+0x05)=0x74; *(p2+0x06)=0x03; *(p2+0x07)=0x03; *(p2+0x08)=0x14; *(p2+0x09)=0x3E; *(p2+0x0A)=0x8B; *(p2+0x0B)=0x48; *(p2+0x0C)=0x20; *(p2+0x0D)=0xE3; *(p2+0x0E)=0x11; *(p2+0x0F)=0x8B; *(p2+0x10)=0x40; *(p2+0x11)=0x24; *(p2+0x12)=0x8B; *(p2+0x13)=0x00; *(p2+0x14)=0x03; *(p2+0x15)=0xC7; *(p2+0x16)=0x29; *(p2+0x17)=0x50; *(p2+0x18)=0xF8; *(p2+0x19)=0x29; *(p2+0x1A)=0x10; *(p2+0x1B)=0x83; *(p2+0x1C)=0xC0; *(p2+0x1D)=0x38; *(p2+0x1E)=0xE2; *(p2+0x1F)=0xF4; VirtualProtect(p2,0x20,OldProtect,&OldProtect); break; } } break; } } } FoxInfo myFoxInfo[]={ {"VFP9FixReportFooter",(FPFI)VFP9FixReportFooter,0,""}, }; FoxTable _FoxTable={ (FoxTable *)0,sizeof(myFoxInfo)/sizeof(FoxInfo),myFoxInfo }; 3, Please refer to the file make.bat: @echo off rem ;-----------------------------------------------; rem ; VFP9fix Maker Program ; rem ; Make.bat ; rem ; (C)Mr. Chen, 2009.11 ; rem ; E-mail: ccb2000@163.com ; rem ;-----------------------------------------------; rem NMAKE /f "vfp9fix.mak" CFG="vfp9fix - Win32 Release" if exist .\vfp9fix.dll del .\vfp9fix.dll if exist .\vfp9fix.obj del .\vfp9fix.obj if exist .\vfp9fix.lib del .\vfp9fix.lib if exist .\vfp9fix.exp del .\vfp9fix.exp if exist .\vfp9fix.pch del .\vfp9fix.pch cl /nologo /Gr /MD /w /W0 /Ox /Ob1 /Os /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Zm1000 /c vfp9fix.c if not exist .\vfp9fix.obj pause link kernel32.lib user32.lib uuid.lib winapims.lib /nologo /subsystem:windows /dll /incremental:no /machine:I386 /out:".\vfp9fix.dll" /implib:".\vfp9fix.lib" ".\vfp9fix.obj" Then run make.bat, we can build a VFP API Library file: vfp9fix.dll. 4, Please refer to the file f_vfp9fixreportfooterwithdll.prg: *PROC f_vfp9fixreportfooterwithdll * VFP 9.0 FIX - REPORT FOOTER with vfp9fix.dll * ccb2000@163.com, 2010.1 PRIVATE m.q_vfp9fixreportfooter m.q_vfp9fixreportfooter=.T. IF ROUND(VAL(CHRTRAN(UPPE(VERSION()),"MICROSOFTVISUALFOXPRO","")),2)=9.0 PRIVATE m.q_errnum,m.q_erroron m.q_errnum=0 m.q_erroron=ON("ERROR") ON ERROR m.q_errnum=ERROR() SET LIBRARY TO ("vfp9fix.dll") ADDITIVE ON ERROR &q_erroron IF .F. PUBLIC vfp9fixreportfooter(1) ENDI IF m.q_errnum#0 m.q_vfp9fixreportfooter=.F. RETU m.q_vfp9fixreportfooter ENDI PRIVATE m.q_errnum,m.q_erroron m.q_errnum=0 m.q_erroron=ON("ERROR") ON ERROR m.q_errnum=ERROR() =vfp9fixreportfooter() ON ERROR &q_erroron IF m.q_errnum#0 m.q_vfp9fixreportfooter=.F. RETU m.q_vfp9fixreportfooter ENDI PRIVATE m.q_errnum,m.q_erroron m.q_errnum=0 m.q_erroron=ON("ERROR") ON ERROR m.q_errnum=ERROR() RELEASE LIBRARY ("vfp9fix.dll") ON ERROR &q_erroron IF m.q_errnum#0 m.q_vfp9fixreportfooter=.F. RETU m.q_vfp9fixreportfooter ENDI m.q_vfp9fixreportfooter=.T. RETU m.q_vfp9fixreportfooter ENDI m.q_vfp9fixreportfooter=.T. RETU m.q_vfp9fixreportfooter * END OF PROC F_VFP9FIXREPORTFOOTERWITHDLL. 5, Please refer to the file f_vfp9fixreportfooter.prg: *PROC f_vfp9fixreportfooter * VFP 9.0 FIX - REPORT FOOTER * ccb2000@163.com, 2010.12 PRIVATE m.q_vfp9fixreportfooter m.q_vfp9fixreportfooter=.T. IF !ROUND(VAL(CHRTRAN(UPPE(VERSION()),"MICROSOFTVISUALFOXPRO","")),2)=9.0 m.q_vfp9fixreportfooter=.T. RETU m.q_vfp9fixreportfooter ENDI DECLARE INTEGER "GetModuleHandle" IN win32api ; STRING lpfilename DECLARE INTEGER "GetCurrentProcess" IN win32api DECLARE INTEGER "ReadProcessMemory" IN win32api ; LONG hprocess,; INTEGER lpbaseaddress,; STRING @lpbuffer,; INTEGER nsize,; INTEGER lpnumberofbytesread DECLARE INTEGER "WriteProcessMemory" IN win32api ; LONG hprocess,; INTEGER lpbaseaddress,; STRING lpbuffer,; INTEGER nsize,; INTEGER lpnumberofbyteswritten DECLARE INTEGER "VirtualProtect" IN win32api ; INTEGER lpaddress,; INTEGER dwsize,; INTEGER flnewprotect,; INTEGER @lpfloldprotect IF .F. PUBLIC getmodulehandle(1) PUBLIC getcurrentprocess(1) PUBLIC readprocessmemory(1) PUBLIC writeprocessmemory(1) PUBLIC virtualprotect(1) ENDIF PRIVATE m.q_hmodule0 m.q_hmodule0=0 m.q_hmodule0=getmodulehandle(_VFP.FULLNAME) IF !m.q_hmodule0>0 m.q_vfp9fixreportfooter=.F. RETU m.q_vfp9fixreportfooter ENDIF * for (i=0x080000;i<0x100000;i++) * { * p1=hmodule0+i; * if (*(p1+0x09)==0x8B && * *(p1+0x0A)==0x50 && * *(p1+0x0B)==0x0C && * *(p1+0x0C)==0x2B && * *(p1+0x0D)==0x56 && * *(p1+0x0E)==0x68 && * *(p1+0x0F)==0x03 && * *(p1+0x10)==0x56 && * *(p1+0x11)==0x58) * { * * // fix vfp9.exe, vfp9r.dll * // 00498A70 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10] * // 00498A73 8078 15 00 CMP BYTE PTR DS:[EAX+15],0 * // 00498A77 75 1A JNZ SHORT VFP9.00498A93 * // 00498A79 8B50 0C MOV EDX,DWORD PTR DS:[EAX+C] * // 00498A7C 2B56 68 SUB EDX,DWORD PTR DS:[ESI+68] * // 00498A7F 0356 58 ADD EDX,DWORD PTR DS:[ESI+58] * // 00498A82 E8 58BBFFFF CALL VFP9.004945DF * // 00498A87 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10] * // 00498A8A 8B4E 68 MOV ECX,DWORD PTR DS:[ESI+68] * // 00498A8D 2B48 0C SUB ECX,DWORD PTR DS:[EAX+C] * // 00498A90 894E 58 MOV DWORD PTR DS:[ESI+58],ECX * * // fix to: * // 00498A70 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10] * // 00498A73 50 PUSH EAX * // 00498A74 BF 14010000 MOV EDI,114 * // 00498A79 8B50 0C MOV EDX,DWORD PTR DS:[EAX+C] * // 00498A7C 2B56 68 SUB EDX,DWORD PTR DS:[ESI+68] * // 00498A7F 0356 58 ADD EDX,DWORD PTR DS:[ESI+58] * // 00498A82 E8 58BBFFFF CALL VFP9.004945DF * // 00498A87 33FF XOR EDI,EDI * // 00498A89 58 POP EAX * // 00498A8A 8B4E 68 MOV ECX,DWORD PTR DS:[ESI+68] * // 00498A8D 2B48 0C SUB ECX,DWORD PTR DS:[EAX+C] * // 00498A90 894E 58 MOV DWORD PTR DS:[ESI+58],ECX PRIVATE m.q_str1 m.q_str1=REPL(CHR(0),0x100000-0x080000) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x080000,@m.q_str1,LEN(m.q_str1),0) PRIVATE m.q_p1_nn m.q_p1_nn=1 DO WHILE .T. PRIVATE m.q_p1 m.q_p1=AT(CHR(0x8b)+; CHR(0x50)+; CHR(0x0c)+; CHR(0x2b)+; CHR(0x56)+; CHR(0x68)+; CHR(0x03)+; CHR(0x56)+; CHR(0x58),m.q_str1,m.q_p1_nn) IF !m.q_p1>0 m.q_vfp9fixreportfooter=.F. RETU m.q_vfp9fixreportfooter ENDIF m.q_p1=m.q_p1-0x09 IF !(SUBS(m.q_str1,m.q_p1+0x09,1)==CHR(0x8b).AND.; SUBS(m.q_str1,m.q_p1+0x0a,1)==CHR(0x50).AND.; SUBS(m.q_str1,m.q_p1+0x0b,1)==CHR(0x0c).AND.; SUBS(m.q_str1,m.q_p1+0x0c,1)==CHR(0x2b).AND.; SUBS(m.q_str1,m.q_p1+0x0d,1)==CHR(0x56).AND.; SUBS(m.q_str1,m.q_p1+0x0e,1)==CHR(0x68).AND.; SUBS(m.q_str1,m.q_p1+0x0f,1)==CHR(0x03).AND.; SUBS(m.q_str1,m.q_p1+0x10,1)==CHR(0x56).AND.; SUBS(m.q_str1,m.q_p1+0x11,1)==CHR(0x58)) m.q_p1_nn=m.q_p1_nn+1 LOOP ENDIF EXIT ENDDO * for (i=0x080000;i<0x100000;i++) * { * p2=hmodule0+i; * if (*(p2+0x0E)==0x05 && * *(p2+0x0F)==0x14 && * *(p2+0x10)==0x01 && * *(p2+0x11)==0x00 && * *(p2+0x12)==0x00 && * *(p2+0x13)==0x29 && * *(p2+0x14)==0x50 && * *(p2+0x15)==0xF8 && * *(p2+0x16)==0x29 && * *(p2+0x17)==0x10) * { * * // fix vfp9.exe, vfp9r.dll * // 004945DF 8B48 20 MOV ECX,DWORD PTR DS:[EAX+20] * // 004945E2 85C9 TEST ECX,ECX * // 004945E4 74 19 JE SHORT VFP9.004945FF * // 004945E6 8B40 24 MOV EAX,DWORD PTR DS:[EAX+24] * // 004945E9 8B00 MOV EAX,DWORD PTR DS:[EAX] * // 004945EB 7E 12 JLE SHORT VFP9.004945FF * // 004945ED 05 14010000 ADD EAX,114 * // 004945F2 2950 F8 SUB DWORD PTR DS:[EAX-8],EDX * // 004945F5 2910 SUB DWORD PTR DS:[EAX],EDX * // 004945F7 05 4C010000 ADD EAX,14C * // 004945FC 49 DEC ECX * // 004945FD 75 F3 JNZ SHORT VFP9.004945F2 * // 004945FF C3 RETN * * // fix to: * // 004945DF 807C3E CC 00 CMP BYTE PTR DS:[ESI+EDI-34],0 * // 004945E4 74 03 JE SHORT VFP9.004945E9 * // 004945E6 03143E ADD EDX,DWORD PTR DS:[ESI+EDI] * // 004945E9 8B48 20 MOV ECX,DWORD PTR DS:[EAX+20] * // 004945EC E3 11 JECXZ SHORT VFP9.004945FF * // 004945EE 8B40 24 MOV EAX,DWORD PTR DS:[EAX+24] * // 004945F1 8B00 MOV EAX,DWORD PTR DS:[EAX] * // 004945F3 03C7 ADD EAX,EDI * // 004945F5 2950 F8 SUB DWORD PTR DS:[EAX-8],EDX * // 004945F8 2910 SUB DWORD PTR DS:[EAX],EDX * // 004945FA 83C0 38 ADD EAX,38 * // 004945FD E2 F4 LOOPD SHORT VFP9.004945F3 * // 004945FF C3 RETN PRIVATE m.q_str2 m.q_str2=REPL(CHR(0),0x100000-0x080000) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x080000,@m.q_str2,LEN(m.q_str2),0) PRIVATE m.q_p2_nn m.q_p2_nn=1 DO WHILE .T. PRIVATE m.q_p2 m.q_p2=AT(CHR(0x05)+; CHR(0x14)+; CHR(0x01)+; CHR(0x00)+; CHR(0x00)+; CHR(0x29)+; CHR(0x50)+; CHR(0xf8)+; CHR(0x29)+; CHR(0x10),m.q_str2,m.q_p2_nn) IF !m.q_p2>0 m.q_vfp9fixreportfooter=.F. RETU m.q_vfp9fixreportfooter ENDIF m.q_p2=m.q_p2-0x0e IF !(SUBS(m.q_str2,m.q_p2+0x0e,1)==CHR(0x05).AND.; SUBS(m.q_str2,m.q_p2+0x0f,1)==CHR(0x14).AND.; SUBS(m.q_str2,m.q_p2+0x10,1)==CHR(0x01).AND.; SUBS(m.q_str2,m.q_p2+0x11,1)==CHR(0x00).AND.; SUBS(m.q_str2,m.q_p2+0x12,1)==CHR(0x00).AND.; SUBS(m.q_str2,m.q_p2+0x13,1)==CHR(0x29).AND.; SUBS(m.q_str2,m.q_p2+0x14,1)==CHR(0x50).AND.; SUBS(m.q_str2,m.q_p2+0x15,1)==CHR(0xf8).AND.; SUBS(m.q_str2,m.q_p2+0x16,1)==CHR(0x29).AND.; SUBS(m.q_str2,m.q_p2+0x17,1)==CHR(0x10)) m.q_p2_nn=m.q_p2_nn+1 LOOP ENDIF EXIT ENDDO * OldProtect=0x20; // PAGE_EXECUTE_READ * VirtualProtect(p1,0x20,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE * *(p1+0x03)=0x50; * *(p1+0x04)=0xBF; * *(p1+0x05)=0x14; * *(p1+0x06)=0x01; * *(p1+0x07)=0x00; * *(p1+0x08)=0x00; * *(p1+0x17)=0x33; * *(p1+0x18)=0xFF; * *(p1+0x19)=0x58; * VirtualProtect(p1,0x20,OldProtect,&OldProtect); * * OldProtect=0x20; // PAGE_EXECUTE_READ * VirtualProtect(p2,0x20,0x40,&OldProtect); // PAGE_EXECUTE_READWRITE * *(p2+0x00)=0x80; * *(p2+0x01)=0x7C; * *(p2+0x02)=0x3E; * *(p2+0x03)=0xCC; * *(p2+0x04)=0x00; * *(p2+0x05)=0x74; * *(p2+0x06)=0x03; * *(p2+0x07)=0x03; * *(p2+0x08)=0x14; * *(p2+0x09)=0x3E; * *(p2+0x0A)=0x8B; * *(p2+0x0B)=0x48; * *(p2+0x0C)=0x20; * *(p2+0x0D)=0xE3; * *(p2+0x0E)=0x11; * *(p2+0x0F)=0x8B; * *(p2+0x10)=0x40; * *(p2+0x11)=0x24; * *(p2+0x12)=0x8B; * *(p2+0x13)=0x00; * *(p2+0x14)=0x03; * *(p2+0x15)=0xC7; * *(p2+0x16)=0x29; * *(p2+0x17)=0x50; * *(p2+0x18)=0xF8; * *(p2+0x19)=0x29; * *(p2+0x1A)=0x10; * *(p2+0x1B)=0x83; * *(p2+0x1C)=0xC0; * *(p2+0x1D)=0x38; * *(p2+0x1E)=0xE2; * *(p2+0x1F)=0xF4; * VirtualProtect(p2,0x20,OldProtect,&OldProtect); PRIVATE m.q_str1 m.q_str1=REPL(CHR(0),0x20) =readprocessmemory(getcurrentprocess(),m.q_hmodule0+0x080000+m.q_p1-1+0x00,@m.q_str1,LEN(m.q_str1),0) m.q_str1=STUFF(m.q_str1,0x03+1,1,CHR(0x50)) m.q_str1=STUFF(m.q_str1,0x04+1,1,CHR(0xbf)) m.q_str1=STUFF(m.q_str1,0x05+1,1,CHR(0x14)) m.q_str1=STUFF(m.q_str1,0x06+1,1,CHR(0x01)) m.q_str1=STUFF(m.q_str1,0x07+1,1,CHR(0x00)) m.q_str1=STUFF(m.q_str1,0x08+1,1,CHR(0x00)) m.q_str1=STUFF(m.q_str1,0x17+1,1,CHR(0x33)) m.q_str1=STUFF(m.q_str1,0x18+1,1,CHR(0xff)) m.q_str1=STUFF(m.q_str1,0x19+1,1,CHR(0x58)) PRIVATE m.q_str2 m.q_str2=CHR(0x80)+; CHR(0x7c)+; CHR(0x3e)+; CHR(0xcc)+; CHR(0x00)+; CHR(0x74)+; CHR(0x03)+; CHR(0x03)+; CHR(0x14)+; CHR(0x3e)+; CHR(0x8b)+; CHR(0x48)+; CHR(0x20)+; CHR(0xe3)+; CHR(0x11)+; CHR(0x8b)+; CHR(0x40)+; CHR(0x24)+; CHR(0x8b)+; CHR(0x00)+; CHR(0x03)+; CHR(0xc7)+; CHR(0x29)+; CHR(0x50)+; CHR(0xf8)+; CHR(0x29)+; CHR(0x10)+; CHR(0x83)+; CHR(0xc0)+; CHR(0x38)+; CHR(0xe2)+; CHR(0xf4) PRIVATE m.q_oldprotect1 m.q_oldprotect1=0x20 && PAGE_EXECUTE_READ =virtualprotect(m.q_hmodule0+0x080000+m.q_p1-1,0x20,0x40,@m.q_oldprotect1) && PAGE_EXECUTE_READWRITE PRIVATE m.q_oldprotect2 m.q_oldprotect2=0x20 && PAGE_EXECUTE_READ =virtualprotect(m.q_hmodule0+0x080000+m.q_p2-1,0x20,0x40,@m.q_oldprotect2) && PAGE_EXECUTE_READWRITE =writeprocessmemory(getcurrentprocess(),m.q_hmodule0+0x080000+m.q_p1-1+0x00,m.q_str1,LEN(m.q_str1),0) =writeprocessmemory(getcurrentprocess(),m.q_hmodule0+0x080000+m.q_p2-1+0x00,m.q_str2,LEN(m.q_str2),0) =virtualprotect(m.q_hmodule0+0x080000+m.q_p1-1,0x20,m.q_oldprotect1,@m.q_oldprotect1) =virtualprotect(m.q_hmodule0+0x080000+m.q_p2-1,0x20,m.q_oldprotect2,@m.q_oldprotect2) m.q_vfp9fixreportfooter=.T. RETU m.q_vfp9fixreportfooter * END OF PROC F_VFP9FIXREPORTFOOTER. 6, Recommend to add the following code to the start program: * VFP9FixReportFooter #IF ROUND(VAL(CHRTRAN(UPPE(VERSION()),"MICROSOFTVISUALFOXPRO","")),2)=9.0 =f_vfp9fixreportfooter() #ENDI Now in vfp9, the report is correct too. Please refer to the picture testreport9-vfp9fix.jpg: 4. APPLIES TO: VFP 9.0.0.2412 VFP 9.0.0.3504 (SP1) VFP 9.0.0.4611 (SP2) VFP 9.0.0.5015 (SP2) VFP 9.0.0.5411 (SP2) VFP 9.0.0.5721 (SP2) VFP 9.0.0.5815 (SP2) VFP 9.0.0.6303 (SP2) VFP 9.0.0.6602 (SP2) VFP 9.0.0.7423 (SP2) The bug has been fixed in VFP Advanced. 5. REFERENCE WEBSITES: 1, baiyujia.com: http://www.baiyujia.com http://www.baiyujia.com/vfpdocuments/f_vfp9fix321.asp 2, meizvfp.com: http://www.mzvfp.com/read.php?tid=84717 http://www.mzvfp.com/read.php?tid=85037 6. OTHER: For reference only, there is no guarantees. Any questions or suggestions, please send me an email at ccb2000@163.com. |