• Announcements

    • xper

      MSFN Sponsorship and AdBlockers!   07/10/2016

      Dear members, MSFN is made available via subscriptions, donations and advertising revenue. The use of ad-blocking software hurts the site. Please disable ad-blocking software or set an exception for MSFN. Alternatively, become a site sponsor and ads will be disabled automatically and by subscribing you get other sponsor benefits.
diamant

Printing with KernelEx 4.5.1

83 posts in this topic

Just adding some more info on the broken save/open dialogs:

Doesn't matter which version of the translation dll is used, doesn't matter if it is located in \system\ or local to the application. The Sumatra open save dialogs don't work.

Using the latest comdlgex.dll ( 3 functions) also doesn't pop the print dialog in sumatra. comdlgex2.dll does enable the print dialog to pop.

Installing ComDlgEx.dll ( 3 functions again) in \system\ broke open and save dialogs in Kmeleon1.6. although some apps still had their open/save dlgs working.

And.... I am using the portable version of Sumatra1.8.

Edited by snuz2
0

Share this post


Link to post
Share on other sites

Plan E: ComDlgEx.7z

  • Like the original plan A, but with wrappers for all functions.
  • Works for opening and saving files as well as printing in SumatraPDF 0.9 and 1.9
  • Requires no '00' dll...
  • ...however requires ImportPatcher (or hex editor) to patch apps.

Installation Method 4:

  • put ComDlgEx.dll in
    1. <system> folder (for multiple apps)
    2. app folder (for single or portable app)

    [*] use hex editor or ImportPatcher on app to change import dependency:

    [DLL replacements]
    COMDLG32.DLL=ComDlgEx.dll


Build environment: MS DevStudio 97 / VC++ 5.0 sp3 / Win98se

Please try others! :yes:

ComDlgEx.c:


// PrintDlgExA.c - jumper, Mar 24, 2012

//***** Standard #define and #include statements *****//

//#define WIN32_LEAN_AND_MEAN
#define STRICT
//#define _USER32_
#include <windows.h>
#include "commdlg.h"


//***** DLL entry point *****//

BOOL APIENTRY _DllMainCRTStartup (HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReserved)
{
return 1;
}


//***** Export functions *****//

typedef struct tagPRINTPAGERANGE {
DWORD nFromPage;
DWORD nToPage;
} PRINTPAGERANGE, *LPPRINTPAGERANGE;

typedef struct tagPDEX {
DWORD lStructSize;
HWND hwndOwner;
HGLOBAL hDevMode;
HGLOBAL hDevNames;
HDC hDC;
DWORD Flags;
DWORD Flags2;
DWORD ExclusionFlags;
DWORD nPageRanges;
DWORD nMaxPageRanges;
LPPRINTPAGERANGE lpPageRanges;
DWORD nMinPage;
DWORD nMaxPage;
DWORD nCopies;
HINSTANCE hInstance;
LPCTSTR lpPrintTemplateName;
LPUNKNOWN lpCallback;
DWORD nPropertyPages;
HPROPSHEETPAGE *lphPropertyPages;
DWORD nStartPage;
DWORD dwResultAction;
} PRINTDLGEX;


HRESULT WINAPI PrintDlgExA (PRINTDLGEX *pPdex)
{
PRINTDLGA pd;
pd.lStructSize = sizeof(PRINTDLG);
pd.hwndOwner = pPdex->hwndOwner;
pd.hDevMode = pPdex->hDevMode;
pd.hDevNames = pPdex->hDevNames;
pd.hDC = pPdex->hDC;
pd.Flags = (pPdex->Flags & PD_RETURNDC)? pPdex->Flags | PD_USEDEVMODECOPIESANDCOLLATE: pPdex->Flags;
pd.nFromPage = 0xFFFF;
pd.nToPage = 0xFFFF;
if (pPdex->nMaxPageRanges) {
pd.nFromPage = (WORD)pPdex->lpPageRanges[0].nFromPage;
pd.nToPage = (WORD)pPdex->lpPageRanges[0].nToPage;
}
pd.nMinPage = (WORD)pPdex->nMinPage;
pd.nMaxPage = (WORD)pPdex->nMaxPage;
pd.nCopies = (WORD)pPdex->nCopies;
pd.hInstance = NULL; //for templates
pd.lCustData = 0;
pd.lpfnPrintHook = NULL; //pPdex->lpCallback; //
pd.lpfnSetupHook = NULL;
pd.lpPrintTemplateName = NULL;
pd.lpSetupTemplateName = NULL;
pd.hPrintTemplate = NULL;
pd.hSetupTemplate = NULL;

if (PrintDlgA (&pd)) {
pPdex->dwResultAction = 1; // Print
pPdex->hDevMode = pd.hDevMode;
pPdex->hDevNames = pd.hDevNames;
pPdex->hDC = pd.hDC;
pPdex->Flags = pd.Flags;
if (pPdex->nMaxPageRanges) {
pPdex->nPageRanges = 1;
pPdex->lpPageRanges[0].nFromPage = pd.nFromPage;
pPdex->lpPageRanges[0].nToPage = pd.nToPage;
}
pPdex->nCopies = pd.nCopies;
} else {
pPdex->dwResultAction = 0; // Cancel
}
return 0; // S_OK;
}


HRESULT WINAPI PrintDlgExW (PRINTDLGEX *pPdex)
{
PRINTDLGW pd;
pd.lStructSize = sizeof(PRINTDLG);
pd.hwndOwner = pPdex->hwndOwner;
pd.hDevMode = pPdex->hDevMode;
pd.hDevNames = pPdex->hDevNames;
pd.hDC = pPdex->hDC;
pd.Flags = (pPdex->Flags & PD_RETURNDC)? pPdex->Flags | PD_USEDEVMODECOPIESANDCOLLATE: pPdex->Flags;
pd.nFromPage = 0xFFFF;
pd.nToPage = 0xFFFF;
if (pPdex->nMaxPageRanges) {
pd.nFromPage = (WORD)pPdex->lpPageRanges[0].nFromPage;
pd.nToPage = (WORD)pPdex->lpPageRanges[0].nToPage;
}
pd.nMinPage = (WORD)pPdex->nMinPage;
pd.nMaxPage = (WORD)pPdex->nMaxPage;
pd.nCopies = (WORD)pPdex->nCopies;
pd.hInstance = NULL; //for templates
pd.lCustData = 0;
pd.lpfnPrintHook = NULL; //pPdex->lpCallback; //
pd.lpfnSetupHook = NULL;
pd.lpPrintTemplateName = NULL;
pd.lpSetupTemplateName = NULL;
pd.hPrintTemplate = NULL;
pd.hSetupTemplate = NULL;

if (PrintDlgW (&pd)) {
pPdex->dwResultAction = 1; // Print
pPdex->hDevMode = pd.hDevMode;
pPdex->hDevNames = pd.hDevNames;
pPdex->hDC = pd.hDC;
pPdex->Flags = pd.Flags;
if (pPdex->nMaxPageRanges) {
pPdex->nPageRanges = 1;
pPdex->lpPageRanges[0].nFromPage = pd.nFromPage;
pPdex->lpPageRanges[0].nToPage = pd.nToPage;
}
pPdex->nCopies = pd.nCopies;
} else {
pPdex->dwResultAction = 0; // Cancel
}
return 0; // S_OK;
}


// Wrappers for classic functions that KernelEx supports
BOOL APIENTRY exChooseColorA (LPCHOOSECOLORA a) { return ChooseColorA (a); }
BOOL APIENTRY exChooseColorW (LPCHOOSECOLORW a) { return ChooseColorW (a); }
BOOL APIENTRY exChooseFontA (LPCHOOSEFONTA a) { return ChooseFontA (a); }
BOOL APIENTRY exChooseFontW (LPCHOOSEFONTW a) { return ChooseFontW (a); }
DWORD APIENTRY exCommDlgExtendedError(VOID) { return CommDlgExtendedError (); }
HWND APIENTRY exFindTextA (LPFINDREPLACEA a) { return FindTextA (a); }
HWND APIENTRY exFindTextW (LPFINDREPLACEW a) { return FindTextW (a); }
short APIENTRY exGetFileTitleA (LPCSTR a, LPSTR b, WORD c) { return GetFileTitleA (a, b, c); }
short APIENTRY exGetFileTitleW (LPCWSTR a, LPWSTR b, WORD c) { return GetFileTitleW (a, b, c); }
BOOL APIENTRY exGetOpenFileNameA(LPOPENFILENAMEA a) { return GetOpenFileNameA (a); }
BOOL APIENTRY exGetOpenFileNameW(LPOPENFILENAMEW a) { return GetOpenFileNameW (a); }
BOOL APIENTRY exGetSaveFileNameA(LPOPENFILENAMEA a) { return GetSaveFileNameA (a); }
BOOL APIENTRY exGetSaveFileNameW(LPOPENFILENAMEW a) { return GetSaveFileNameW (a); }
HBITMAP WINAPI LoadAlterBitmap (int id, DWORD rgbReplace, DWORD rgbInstead);
HBITMAP WINAPI exLoadAlterBitmap (int a, DWORD b, DWORD c) { return LoadAlterBitmap (a, b, c); }
BOOL APIENTRY exPageSetupDlgA (LPPAGESETUPDLGA a) { return PageSetupDlgA (a); }
BOOL APIENTRY exPageSetupDlgW (LPPAGESETUPDLGW a) { return PageSetupDlgW (a); }
BOOL APIENTRY exPrintDlgA (LPPRINTDLGA a) { return PrintDlgA (a); }
BOOL APIENTRY exPrintDlgW (LPPRINTDLGW a) { return PrintDlgW (a); }
HWND APIENTRY exReplaceTextA (LPFINDREPLACEA a) { return ReplaceTextA (a); }
HWND APIENTRY exReplaceTextW (LPFINDREPLACEW a) { return ReplaceTextW (a); }

ComDlgEx.def:


LIBRARY ComDlgEx
VERSION 4.20.1.1
;BASE 0x7FE00000

EXPORTS
nn100=ComDlg32.@100 @100 NONAME
ChooseColorA=exChooseColorA @101
ChooseColorW=exChooseColorW @102
ChooseFontA=exChooseFontA @103
ChooseFontW=exChooseFontW @104
CommDlgExtendedError=exCommDlgExtendedError @105
FindTextA=exFindTextA @106
FindTextW=exFindTextW @107
GetFileTitleA=exGetFileTitleA @108
GetFileTitleW=exGetFileTitleW @109
GetOpenFileNameA=exGetOpenFileNameA @110
GetOpenFileNameW=exGetOpenFileNameW @111
GetSaveFileNameA=exGetSaveFileNameA @112
GetSaveFileNameW=exGetSaveFileNameW @113
LoadAlterBitmap=exLoadAlterBitmap @114
PageSetupDlgA=exPageSetupDlgA @115
PageSetupDlgW=exPageSetupDlgW @116
PrintDlgA=exPrintDlgA @117
PrintDlgW=exPrintDlgW @118
ReplaceTextA=exReplaceTextA @119
ReplaceTextW=exReplaceTextW @120
WantArrows=ComDlg32.WantArrows @121
dwLBSubclass=ComDlg32.dwLBSubclass @122
dwOKSubclass=ComDlg32.dwOKSubclass @123
PrintDlgExA
PrintDlgExW

Ssync_ANSI_UNICODE_Struct_For_WOW has been removed.

Edited by jumper
0

Share this post


Link to post
Share on other sites

The problem turned out to be that KernelEx is needed for GetOpenFileNameW, but undesired for PrintDlgExW (and vice versa for ComDlgEx) . KernelEx also can't process ComDlg32 functions unless they are imported (not export-forwarded) from a DLL named ComDlg32.dllicon13.gif

So the solution was two-fold:

  • switch from export-forwarding to wrappers of imported functions
  • use dependency order App->ComDlgEx->ComDlg32

Using the previous test versions, KernelEx processing was either fully enabled or fully disabled--meaning it allowed GetOpenFileNameW to work but returned an error for PrintDlgExW, or the new PrintDlgExW worked but GetOpenFileNameW was not patched to work. This affected apps that use the Wide functions: SumatraPDF 1.8, 1.9, and apparently FireFox 3.

Apps (like SumatraPDF 0.9) that use the Ansi functions don't need a KernelEx patch for GetOpenFileNameA, so could print and open files under some install methods (when redirected).

[if requested, I'll expand the above to explain in more detail why each function worked (or didn't) on each app for each method.]

icon11.gif Because KernelEx 4.5.1 does some processing of most of the functions in ComDlg32, I will next try to break out all of that code into a stand-alone DLL into which I can add the new PrintDlgEx code. If successful, this new DLL would be installed using an easier Method 2 (without the renaming or copying). It would also be an example of how KernelEx can be extended without recompiling the full core package.

0

Share this post


Link to post
Share on other sites

The problem turned out to be that KernelEx is needed for GetOpenFileNameW, but undesired for PrintDlgExW (and vice versa for ComDlgEx) . KernelEx also can't process ComDlg32 functions unless they are imported (not export-forwarded) from a DLL named ComDlg32.dllicon13.gif

So the solution was two-fold:

  • switch from export-forwarding to wrappers of imported functions
  • use dependency order App->ComDlgEx->ComDlg32

Using the previous test versions, KernelEx processing was either fully enabled or fully disabled--meaning it allowed GetOpenFileNameW to work but returned an error for PrintDlgExW, or the new PrintDlgExW worked but GetOpenFileNameW was not patched to work. This affected apps that use the Wide functions: SumatraPDF 1.8, 1.9, and apparently FireFox 3.

Apps (like SumatraPDF 0.9) that use the Ansi functions don't need a KernelEx patch for GetOpenFileNameA, so could print and open files under some install methods (when redirected).

[if requested, I'll expand the above to explain in more detail why each function worked (or didn't) on each app for each method.]

icon11.gif Because KernelEx 4.5.1 does some processing of most of the functions in ComDlg32, I will next try to break out all of that code into a stand-alone DLL into which I can add the new PrintDlgEx code. If successful, this new DLL would be installed using an easier Method 2 (without the renaming or copying). It would also be an example of how KernelEx can be extended without recompiling the full core package.

I was able to print with SumatraPDF 1.9 using a DLL containing PrintDlgExW and my DLLHOOK redirector.

I used a debugged version of jumper's code from Post #8 to create the DLL.

0

Share this post


Link to post
Share on other sites

Confirming the latest works for me on Sumatra 1.8. I don't see any way it could possibly break anything else either. Thanks very much.

0

Share this post


Link to post
Share on other sites

Great, I can print with Sumatra PDF 1.9 (method 4b / ImportPatcher). :thumbup

I have printed successfully with Firefox 3.6.28 and Seamonkey 2.6.1, too. :thumbup

Firefox 3.5.19 crashed once during testing.

Seamonkey 2.0.14 isn't stable in order to print.

Edited by schwups
0

Share this post


Link to post
Share on other sites

I have printed successfully with Firefox 3.6.28 and Seamonkey 2.6.1, too. :thumbup

Seamonkey 2.0.14 isn't stable in order to print.

Hi Schwups,

based on my previous experiences in getting Seamonkey 2.0.14 reliably to print and since I don't want to play around with the registry I did the following.

1) In <winsysdir>, copy original COMDLG32.DLL to COMDLG00.DLL.

2) Place ComDlg32.dll in app folder AND into Windows Kernel Ex folder !!!

When SM 2.0.14 is running open the print preview - wait a few seconds - close the preview and after that I can print without any problems. But this may be working only for me because I changed many things on my system before finding this awesome board !!

Thank you very much Jumper and everybody else !!

Oh by the way Schwups, on higher versions than 2.0.14 websites look like crap on my system !! Is it working for you ??

Edited by MiKl
0

Share this post


Link to post
Share on other sites

Higher versions of SeaMonkey work for me with comp. mode Win XP (Win ME / KernelEX 4.5.2 / CPU SSE2 or 3). Recently visited addresses, history, bookmarks and the Java Sun plugin don't work.

Fixed with KernelEX 4.5.2: Firefox 4+ : Freeze when drawing a non-blank page. Seamonkey versions 2.1 - 2.6.1 are based on the same Gecko engines as Firefox 4 - 9.0.1 and should work. KernelEX Wiki

Edited by schwups
0

Share this post


Link to post
Share on other sites

It doesn't work for PDF XChangeViewer. The progam crashes in order to print. Tested with versions 2.5.201, 2.5.192, 2.0.42.3. Pdfxcview has caused an error in unknown module. It is the same error as before without the update.

0

Share this post


Link to post
Share on other sites

I get an error message in order to print with Palemoon. It can also be after printing of one page. Palemoon caused an error in Kernel32.dll. Palemoon will now close. Tested on some ME machines.

0

Share this post


Link to post
Share on other sites

I get an error message in order to print with Palemoon. It can also be after printing of one page. Palemoon caused an error in Kernel32.dll. Palemoon will now close. Tested on some ME machines.

What were the error details and Kernel32.dll version?

If we cross-reference the instruction address/EIP value with Kernel32.dll function export addresses using a PE viewer, we should be able to determine what function was running. (In the case of your previous post, the Stack dump should reveal what module--and possibly function--might have jumped into unknown memory.)

If you have VC++ installed, click on [Debug] in the error dialog to launch it. Then View->Debug Windows->Call Stack to see the calling sequence.

I'll try to write a JIT debugger (based on FineSSE) that looks up the call sequence (and maybe offers a live recovery attempt!).

0

Share this post


Link to post
Share on other sites

What were the error details and Kernel32.dll version? It is the orig. Win ME Kernel32.dll 4.90.0.3000  / 08.06.2000 17:00

post-266873-0-80437400-1333547892_thumb.

post-266873-0-15222500-1333547921_thumb.

0

Share this post


Link to post
Share on other sites

It is the orig. Win ME Kernel32.dll 4.90.0.3000 / 08.06.2000 17:00

According to this link:


LoadLibraryA("KERNEL32.DLL") - returns BFF70000h on w98se
- returns BFF60000h on winME
- returns 77E80000h on w2k

Google translates the error message to:


Palemoon caused an error by a
invalid page
in module KERNEL32.DLL at 01ef: bff6a4e9
...
Stack dump:
00650050 00000000 004c000c 004c0000 004c985c
00000040 00000000 00000b19 000004ca 0095e748
bff6a6b1 004c0000 004c985c 00000018 00000040
00000013

Subtracting bff60000 from bff6a4e9 and bff6a6b1 and looking up those addresses for Kernel32.dll in Dependency Walker indicates that the error happened in a support function called by IsBadWritePtr.

Apps usually load at 00400000, so all those 0040xxxx values on the stack are probably data pointers within Palemoon.

0

Share this post


Link to post
Share on other sites

According to this link:


LoadLibraryA("KERNEL32.DLL") - returns BFF70000h on w98se
- returns BFF60000h on winME
- returns 77E80000h on w2k

Here's a small app that returns the load address of any library.

Usage: loaddr libraryname.dll

Hope it may be useful.

It returns kernel32.dll's load address = 0x7C800000 on XP SP3.

@all: Please do test it on 9x/ME, to confirm it works OK.

LOADDR.7z

Edited by dencorso
Replaced buggy app with fixed one.
0

Share this post


Link to post
Share on other sites

@dencorso:

Maybe I'm using it incorrectly, but W98SE loader reports it is improperly linked with alignment less than 0x1000 and refuse to load.

0

Share this post


Link to post
Share on other sites
Maybe I'm using it incorrectly, but W98SE loader reports it is improperly linked with alignment less than 0x1000 and refuse to load.

:blink: No, you're doing nothing wrong.

I forgot to link it the way 9x/ME likes... My bad, sorry! :blushing:

Redownload, please, I've fixed it now.

Thanks for the swift feedback. You rock! :thumbup

0

Share this post


Link to post
Share on other sites

According to this link:


LoadLibraryA("KERNEL32.DLL") - returns BFF70000h on w98se
- returns BFF60000h on winME
- returns 77E80000h on w2k

@all: Please do test it on 9x/ME, to confirm it works OK.

So now we have:


LoadLibraryA("KERNEL32.DLL") - returns BFF70000h on Win 95 OSR2.5 (determined by LoneCrusader)
- returns BFF70000h on Win 98SE (confirmed by dencorso and snuz2)
- returns BFF60000h on Win ME (confirmed by loblo)
- returns 77E80000h on Win 2k
- returns 7C570000h on Win 2k Adv Srv (determined by tomasz86)
- returns 7C800000h on Win XP Pro SP3 (determined by dencorso)

:angel Well, now that LOADDR.EXE is working right...

@LoneCrusader: would you please determine the value for Win 95 OSR2.5,?

@loblo: would you please confirm the value for Win ME?

@jaclaz: would you please confirm/determine the value for Win XP Pro SP2?

@tomasz86: would you please confirm the value for Win 2k (or determine a new value, since you use a server version, right?)?

0

Share this post


Link to post
Share on other sites
@loblo: would you please confirm the value for Win ME?

It returns 0xBFF60000, OK.

0

Share this post


Link to post
Share on other sites

@LoneCrusader: would you please determine the value for Win 95 OSR2.5,?

Tested with 95C OSR2.5 with all official USB updates installed (USB Updates contain a major KERNEL32 version change)

And using the last KERNEL32.DLL for Windows 95, v4.03.1216.

loaddr v.0.1, freeware by dencorso, 2012

kernel32.dll's load address = 0xBFF70000

When I get a chance I will test again on an installation without USB (=v4.00.1112)

Tested on Pre-USB OSR2. Result is the same.

EDIT - Added Pre-USB 95 test results.

Edited by LoneCrusader
0

Share this post


Link to post
Share on other sites

Thanks a lot to you both for your swift replies! :thumbup

I've updated that table in my previous post to reflect your results.

You rock! :thumbup

0

Share this post


Link to post
Share on other sites

@tomasz86: would you please confirm the value for Win 2k (or determine a new value, since you use a server version, right?)?

I've got 0x7C570000 here (W2K Adv Srv).

0

Share this post


Link to post
Share on other sites

i happened to find a winXP pro sp2 (x86) in my works (build 2600.xpsp_sp2_qfe.061030-0020 : Service Pack 2)

and i tried the loaddr on that machine.

the result was:

loaddr v.0.1, freeware by dencorso, 2012

kernel32.dll's load address = 0x7C800000

0

Share this post


Link to post
Share on other sites

OK! :) So now we have:


LoadLibraryA("KERNEL32.DLL") - returns BFF70000h on Win 95 OSR2.5 (determined by LoneCrusader)
- returns BFF70000h on Win 98SE (confirmed by dencorso and snuz2)
- returns BFF60000h on Win ME (confirmed by loblo)
- returns 77E80000h on Win 2k Pro
- returns 7C570000h on Win 2k Adv Srv (determined by tomasz86)
- returns 7C800000h on Win XP Pro SP2 (determined by Joseph_sw)
- returns 7C800000h on Win XP Pro SP3 (determined by dencorso)

My most wholehearted thanks to those who helped test LOADDR so swiftly! :yes:

I think, by now, my program LOADDR.EXE is suffciently tested and validated to be used reliably, whenever necessary, with any dll. It is intended to be used as a tool, together with Dependency Walker, to help finding out more info from Program Error Message Boxes, as outlined by jumper in post #38.

However, interestingly, the originally intended purpose of LOADDR notwithstanding, the small collection of load addresses for Kernel32.dll collected here do, in fact, appear to show that:

1) It may possible to differenciate the Windows OS families based solely on the kernel32's the load address, since Win 9x/ME use 0xBFFX0000, while the NT-family prefer 0x7XXX0000;

2) Service packs seem not to influence the load address used, but Client as opposed to Server variants do.

And Happy Easter to you all!

0

Share this post


Link to post
Share on other sites

My most wholehearted thanks to those who helped test LOADDR so swiftly! :yes:

I think, by now, my program LOADDR.EXE is suffciently tested and validated to be used reliably, whenever necessary, with any dll. It is intended to be used as a tool, together with Dependency Walker, to help finding out more info from Program Error Message Boxes, as outlined by jumper in post #38.

However, interestingly, the originally intended purpose of LOADDR notwithstanding, the small collection of load addresses for Kernel32.dll collected here do, in fact, appear to show that:

1) It may possible to differenciate the Windows OS families based solely on the kernel32's the load address, since Win 9x/ME use 0xBFFX0000, while the NT-family prefer 0x7XXX0000;

2) Service packs seem not to influence the load address used, but Client as opposed to Server variants do.

And Happy Easter to you all!

I've been using this batch file with LOADDR to avoid opening DOS boxes:

@%0\..\LOADDR.EXE %1

I'm on SE (BFF7) and realized the Kernel32 base on ME must be different per the error info. Kernel32 doesn't contain relocation data, so must load at its preferred base. Clearly that's different for many versions and apparently in the NT-family has been moved from the Reserved System Arena (Holds ring-0 components) Shared Arena down to the Shared Private Arena [MSKB 125691].

Could you possibly extend LOADDR to also report the preferred base if different?

EDIT: Thanks RLoew! :thumbup

Edited by jumper
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.