Tuesday, April 29, 2008

You'll be Missed, Ken

Eric posted on Foxite that MVP Ken Murphy passed away on Sunday. This is very sad news. In addition to being a very nice guy, Ken was a great resource to the VFP community, so he will most definitely be missed. I'm glad I got to spend a week hanging out with him at the MVP Summit two weeks ago. My condolences to his family.

MVP Summit

As Rick blogged, VFP MVPs had a chance to spend some quality time with several members of the VFP team from Microsoft at the MVP Summit held a couple of weeks ago in Seattle. Here's a picture from that meeting:

vfp gang

Back row: Richard Stanton, Milind Lele, Alan Griver, Igor Vit, Craig Berntson, Doug Hennig, Olaf Doschke, Ken Murphy, Francis Faure

Front row: Tamar Granor, Rick Schummer, Cathy Pountney, Christof Wollenhaupt, Alex Feldstein, Rainer Becker

Canadians made a big impact at the conference. We even got Steve Ballmer to wear a Canada hockey jersey! Here's a picture of our group:

Canadians_MVP_Summit_2008_stairs

Friday, April 04, 2008

Using Cryptor DLL Functions

If you use Cryptor from XiTech for encryption in VFP, you may be aware that its FLL is sensitive to the version of VFP you're using. For example, C40Fox80.FLL is for VFP 8, C40Fox70.FLL is for VFP 7, etc. Although Cryptor 5 has been available for some time, I haven't bothered to upgrade because version 4 does everything I need it to. Also, there are some installation issues with Cryptor 5 on Vista, since it's now a COM object, while version 4 doesn't need registration. One problem with version 4, though, is that it doesn't come with an FLL for VFP 9.

Fortunately, you don't need one. Cryptor comes with a DLL, XICrCore.DLL, that contains functions providing Cryptor features. I use a class called SFCryptor that's a wrapper for the DLL. You can download it from the Technical Papers page of my Web site.

Here are the declarations for these functions:

lcDLL = fullpath('XICrCore.dll', addbs(.cCryptorPath))
declare integer CRYIni_Initialize      in (lcDLL) ;
    integer LoadMode
declare integer CRYIni_InitializeEx    in (lcDLL) ;
    integer dwLoadMode, integer hModule, string strExclusionList
declare integer CRYIni_UnInitialize    in (lcDLL)
declare integer CRYUtl_EncodeString    in (lcDLL) ;
    string strSrc, string @ strDest, integer dwLength, ;
    string strPassword, integer dwMethod
declare integer CRYUtl_DecodeString    in (lcDLL) ;
    string strSrc, string @ strDest, integer dwLength, ;
    string strPassword, integer dwMethod
declare string  CRYUtl_GetErrorMessage in (lcDLL) ;
    integer errorCode
declare integer CRYUtl_Encode          in (lcDLL) ;
    string strFilename, string strPassword, string strBackupExt, ;
    integer bKeepBackup, integer dwMethod
declare integer CRYUtl_Decode          in (lcDLL) ;
    string strFilename, string strPassword, string strBackupExt, ;
    integer bKeepBackup, integer dwMethod
declare integer CRYMan_Register        in (lcDLL) ;
    string strFilename, string strPassword, integer dwFlags, ;
    integer dwMethod
declare integer CRYMan_Unregister      in (lcDLL) ;
    string strFilename
declare integer CRYMan_List            in (lcDLL) ;
    integer dwFunction, string @ strFilename, integer @ pdwFlags, ;
    integer @ pdwMethod, integer @ pdwCount


This code initializes Cryptor:



#define CRYPTOR_ERR_SUCCESS             0x00000000
#define CRYPTOR_ERR_ALREADY_INITIALIZED 0xFFFFFF02 - 0x100000000
if version(2) = 0
    declare integer GetModuleHandle in Win32API string ModuleName
    lnHookModule = GetModuleHandle('VFP' + ;
        left(transform(version(5)), 1) + 'R.DLL')
    if lnHookModule <> 0
        lnStatus = CRYIni_InitializeEx(2, lnHookModule, ';')
    else   
        lnStatus = -1
    endif lnHookModule <> 0
else
    lnStatus = CRYIni_InitializeEx(2, 0, ';')
endif version(2) = 0
if inlist(lnStatus, CRYPTOR_ERR_SUCCESS, ;
    CRYPTOR_ERR_ALREADY_INITIALIZED)
    llInitialized = .T.
else
    lcErrorMessage = 'Could not initialize Cryptor: status ' + ;
        'code ' + transform(lnStatus)
    llInitialized = .F.
endif inlist(lnStatus ...


This code registers, unregisters, encrypts, or decrypts a file; pass it the filename, password, encryption method, and "register" to register the file, "unregister" to unregister it, "encrypt" to encrypt it, or "decrypt" to decrypt it. Error handling code was removed for brevity.



lparameters tcFileName, ;
    tcPassword, ;
    tnMethod, ;
    tcProcess
local laFiles[1], ;
    lnFiles, ;
    lcPath, ;
    lnI, ;
    lcFile, ;
    lnStatus, ;
    llReturn

* Get the file to process. Use ADIR() because we may a file skeleton
* like SOMETHING.*.

lnFiles = adir(laFiles, tcFileName)

* Try to process the file(s).

lcPath = addbs(justpath(tcFileName))
for lnI = 1 to lnFiles
lcFile = lower(lcPath + laFiles[lnI, 1])
do case
case tcProcess = 'encrypt'
         lnStatus = CRYUtl_Encode(lcFile, tcPassword, .NULL., 0, ;
             tnMethod)
      case tcProcess = 'decrypt'
         lnStatus = CRYUtl_Decode(lcFile, tcPassword, .NULL., 0, ;
              tnMethod)
      case tcProcess = 'register'
          lnStatus = CRYMan_Register(lcFile, tcPassword, 0, tnMethod)
      case tcProcess = 'unregister'
          lnStatus = CRYMan_Unregister(lcFile)
    endcase
    llReturn = lnStatus = CRYPTOR_ERR_SUCCESS
    if not llReturn
        lcErrorMessage = 'Could not ' + tcProcess + ' ' + lcFile + ;
            ': ' + CRYUtl_GetErrorMessage(lnStatus)
       exit
  endif not llReturn
next lnI
return llReturn

Thursday, April 03, 2008

No More FoxForward

I was bummed to read that Kevin Cully doesn't plan to continue with the FoxForward conference. Although I hadn't attended one myself, I heard lots of good things about it. More importantly, I hate to see another conference go by the wayside. Now Southwest Fox is the only North American VFP conference.

I can't imagine how one person can do all the planning for a conference. Rick Schummer, Tamar Granor, and I work our butts off planning Southwest Fox and that's with three of us! Maybe some folks in the Atlanta area will pick up from where Kevin left off, and hopefully there will be several people involved so it doesn't fall onto one person's shoulders.

Tuesday, April 01, 2008

New Releases

Today we released version 3.2 of the following Stonefield Query products:

  • Stonefield Query SDK
  • Stonefield Query for Sage Accpac ERP (formerly ACCPAC Query for Sage Accpac ERP)
  • Stonefield Query for Sage Pro ERP (formerly ACCPACP Query for Sage Pro ERP)

For details on these releases, see our Stonefield Query blog.

Over the next couple of weeks, we'll release version 3.2 of the rest of the products:

  • Stonefield Query for AccountMate
  • Stonefield Query for ACT!
  • Stonefield Query for Alere
  • Stonefield Query for GoldMine
  • Stonefield Query for HEAT
  • Stonefield Query for QuoteWerks
  • Stonefield Query for Sage BusinessVision (a new product)
  • Stonefield Query for Sage Timberline Office
  • Stonefield Query for SalesLogix
  • Stonefield Query for Simply Accounting

We're also working on a version of Stonefield Query for MAS 90/200, which will be released in time for the Sage Insights conference in May.

Google April Fools

I think I've gotten more response from my There Will be a VFP 10! posting than any other, and it's still only the morning!

Jeff Hibbs pointed me to a great Google April Fools joke: http://www.google.com/tisp/. Be sure to follow the links to see how it's installed.

Someone (sorry, I don't remember who) posted another Google joke on a forum: http://mail.google.com/mail/help/customtime/index.html. I know I can definitely use that feature.

There Will be a VFP 10!

Microsoft announced early this morning that they've changed their minds and will release version 10 of Visual FoxPro after all. Their plans are ambitious: lifting the 2 GB limit on table size, making VFP a fully-compliant .NET language, integrating the Microsoft WSYP error handler, and so on.

Plans call for ten months of development and a two-month beta. They expect to release VFP 10 on this day next year.