Primary Extender conversion tasks

  1. Delete old DLLs and temp files

    In your Extender Project directory, and in the RELEASE and DEBUG directories, delete the old DLLs and also any files with a 34i extension and possibly other temp OBJ files and stuff, as we will be changing the name of the output file to 44I in subsequent steps.
  2. Fix output file name

    In Visual C, settings, LINK tab, change the output file name for BOTH Release and Debug builds from xxx.34i.dll to xxx.44i.dll

  3. Update resource file version information

    1. Update fileversion information to match extender version information
    2. Update product version to 2004
    3. Update Copyright notice to 2004
    4. Update original filename so it shows the 44i extension
    5. update internal name so it show the 44i extension

  4. Update EXTENDERVERSION in source code

    In your source code increment the EXTENDERVERSION define to the next number

  5. Define InterfaceLevel and Extender_Feature_Level

    Add the INTERFACELEFEL define to your code someplace. Usually top of C program or H file someplace.

    If you do not have EXTENDER_FEATURE_LEVEL in your code add it in.

    	#define INTERFACELEVEL  4              // extender interface level (DON'T CHANGE!)
    	#define EXTENDER_FEATURE_LEVEL 1004    // required BATDLL feature interface level
    
      

  6. Update ADDONS.H file

    
    // Addons.h   Addons file for WIL extenders
    //
    // This can be used to build version 2/3/4/5/6 extenders
    //
    // INTERFACELEVEL must be defined before including this header
    
    #ifndef _ADDONS_H_
    #define _ADDONS_H_
    
    typedef LPVOID LPBDS;                  // not really
    typedef LPVOID LPRESULTVAR;            // not really
    typedef LONG (FARPASCAL * DLLSERVICES) (HGLOBAL, WORD, LPSTR, LPSTR, int, DWORD);
    
    typedef int FAR PASCAL AddOnCallback (int, LONG, LPSTR, BOOL, LONG, LPSTR);
    typedef AddOnCallback FAR *lpAddOnCallback;
    
    #define VARTYPE_UNDEF         0        // These are bitmapped, var can be both
    #define VARTYPE_INT           1        // Numeric and string, must check bits
    #define VARTYPE_STRING        2
    #define VARTYPE_FILE          5        // FILE and INT bits set
    #define VARTYPE_OLEOBJECT    17        // OLE AND INT bits set
    #define VARTYPE_FLOATNUM     32        // floating point
    #define VARTYPE_BINARY       65        // BINARY and INT bits set
    #define VARTYPE_ARRAY       256        // an array
    #define VARTYPE_VARIANT     512        // a COM (OLE) variant
    
    typedef struct vipervariable2          // version 2/3 variable
    {
      double  flt;                         // 8-byte floating point number
      LONG    x;                           // if int variable, value is here
      int     inittype;                    // 0=uninitialized 1=int 2=string 3=both  yes can have both sometimes
      union
      {
        LPSTR lpstr;                       // pointer to string in string table
        DWORD handle;                      // handle for miscellaneous object types
      };
    } vipervar2, FAR *LPVIPERVAR2;
    
    typedef struct vipervariable4          // version 4 variable
    {
      VARIANT variant;                     // if Variant, variable here.
      double  flt;                         // 8-byte floating point number
      LONG    x;                           // if int variable, value is here
      int     inittype;                    // 0=uninitialized 1=int 2=string 3=both  yes can have both sometimes
      union
      {
        LPSTR lpstr;                       // pointer to string in string table
        DWORD handle;                      // handle for miscellaneous object types
      };
      LONG    reserved;                    // reserved for future expansion
    } vipervar4, FAR *LPVIPERVAR4;
    
    #if INTERFACELEVEL == 4
      #define vipervar vipervar4
      #define LPVIPERVAR LPVIPERVAR4
    #elif INTERFACELEVEL >= 2
      #define vipervar vipervar2
      #define LPVIPERVAR LPVIPERVAR2
    #else
      #error INTERFACELEVEL is invalid or undefined
    #endif
    
    /*----------------------------------------------------------------------------
    LONG FARPASCAL DllVarHandler(HGLOBAL hBatData, LPSTR lpVarName, LPVIPERVAR vv, UINT uVarSize, LONG nRequest)
    
      hBatData   =  lpViperStruct->hBatData
      lpVarName  =  name of WIL variable
      vv         =  vipervar for input or output, depending on request
      uVarSize   =  sizeof(vipervar)
      nRequest   =  operation to perform:
        1  =  get value             (vv = output value)
        2  =  set (and clear) value (vv = value to set)
        3  =  clear value           (vv = 0)
    
      Returns 0 on success, or a positive value on error:
         1  Function failed
         2  Invalid lpVarName
         3  lpVarName too long
         4  vv buffer too small
         5  GlobalLock(hBatData) failed
         6  GlobalLock(hVarHandle) failed
         7  Specified variable name not found
         8  Error getting variant value
         9  Variable table is full
        10  Error setting variant value
        11  Error allocating memory for string
        12  Invalid request
    -----------------------------------------------------------------------------*/
    
    typedef LONG (FARPASCAL * DLLVARHANDLER) (HGLOBAL, LPSTR, LPVIPERVAR, UINT, LONG);
    
    /*---------------------------------------------------------------------------
    LONG FARPASCAL DllArrHandler(HGLOBAL hBatData, LPVIPERVAR arr, DWORD dwSub1, DWORD dwSub2, DWORD dwSub3, DWORD dwSub4, DWORD dwSub5, LPVIPERVAR vv, UINT uVarSize, LONG nRequest)
    
      hBatData  =  lpViperStruct->hBatData
      arr       =  vipervar identifying array
      dwSub1 - dwSub5  =  subscripts identifying array element
      vv        =  vipervar for input or output, depending on request
      uVarSize  =  sizeof(vipervar)
      nRequest  =  operation to perform:
        1  =  get value             (vv = output value)
        2  =  set (and clear) value (vv = value to set)
        3  =  clear value           (vv = 0)
    
      Returns 0 on success, or a positive value on error:
         1  Function failed
         2  arr buffer too small
         3  arr variable is not an array
         4  Array is empty or invalid
         5  Array data is invalid
         6  vv buffer too small
         7  GlobalLock(hBatData) failed
         8  Subscript out of bounds
         9  Error accessing array data
        10  Error reading or writing array data
        11  GlobalLock(hVarHandle) failed
        12  Error getting variant value
        13  Cannot create an embedded array
        14  Error setting variant value
        15  Error allocating memory for string
        16  Invalid request
    -----------------------------------------------------------------------------*/
    
    typedef LONG (FARPASCAL * DLLARRHANDLER) (HGLOBAL, LPVIPERVAR, DWORD, DWORD, DWORD, DWORD, DWORD, LPVIPERVAR, UINT, LONG);
    
    /*---------------------------------------------------------------------------
    LONG FARPASCAL DllArrayServices(HGLOBAL hBatData, LPVIPERVAR arr, UINT uVarSize, LPBYTE lpBuf, UINT uBufSize, LONG nRequest)
    
      hBatData  =  lpViperStruct->hBatData
      arr       =  vipervar identifying array
      uVarSize  =  sizeof(vipervar)
      lpBuf     =  buffer for input or output, depending on request (cast to LPBYTE)
      uBufSize  =  size of buffer pointed to by lpBuf
      nRequest  =  operation to perform:
        1  =  get array info    (lpBuf = pointer to DLLARRAYSERVICES1 structure)
        2  =  create array      (lpBuf = pointer to DWORD[5] containing array dimensions
        3  =  initialize array  (lpBuf = vipervar containing value to set)
        4  =  free array        (lpBuf = 0)
    
      Returns 0 on success, or a positive value on error:
         1  Function failed
         2  arr buffer too small
         3  arr variable is not an array
         4  Array is empty or invalid
         5  GlobalLock(hBatData) failed
         6  GlobalLock(hVarHandle) failed
         7  lpBuf buffer too small
         8  Create array failed: Invalid dimension
         9  Create array failed: Cannot have 0 dimension followed by non-0 dimension
        10  Create array failed: Array too large
        11  Create array failed: Unable to allocate or lock memory
        12  Initialize array failed: Value is invalid type
        13  Initialize array failed: Array is empty
        14  Initialize array failed: Error accessing array data
        15  Initialize array failed: Out of memory for strings
        16  Invalid request
    -----------------------------------------------------------------------------*/
    
    typedef LONG (FARPASCAL * DLLARRAYSERVICES) (HGLOBAL, LPVIPERVAR, UINT, LPBYTE, UINT, LONG);
    
    /*---------------------------------------------------------------------------
    LONG FARPASCAL DllBinaryServices(HGLOBAL hBatData, LONG nBinBuf, LONG nData, LONG nRequest)
    
      hBatData  =  lpViperStruct->hBatData
      nBinBuf   =  binary buffer handle
      nData     =  additional data, depending on request
      nRequest  =  operation to perform:
        1  =  allocate buffer      (nData = buffer size)  (return = buffer handle)       (nBinBuf = 0)
        2  =  deallocate buffer    (nData = 0)            (return = 0)
        3  =  get pointer to data  (nData = 0)            (return = LPSTR cast to LONG)
        4  =  get binary EOD       (nData = 0)            (return = binary EOD)
        5  =  get buffer size      (nData = 0)            (return = buffer size)
        6  =  set binary EOD       (nData = new EOD)      (return = previous EOD)
    
      Returns a non-negative value on success, or a negative value on error:
         -1  Function failed
         -2  Invalid binary buffer handle
         -3  GlobalLock(hBatData) failed
         -4  GlobalLock(hVarHandle) failed
         -5  Too many open binary buffers
         -6  Unable to allocate or lock binary buffer
         -7  Specified EOD beyond end of buffer
         -8  Invalid request
    -----------------------------------------------------------------------------*/
    
    typedef LONG (FARPASCAL * DLLBINARYSERVICES) (HGLOBAL, LONG, LONG, LONG);
    
    /*---------------------------------------------------------------------------
    LONG FARPASCAL DllStoreErrorInfo(HGLOBAL hBatData, LPSTR lpErrorInfo)
    
      hBatData     =  lpViperStruct->hBatData
      lpErrorInfo  =  error information string to store
    
      Returns 0 on success, or a positive value on error:
         1  Function failed
         2  GlobalLock(hBatData) failed
    -----------------------------------------------------------------------------*/
    
    typedef LONG (FARPASCAL * DLLSTOREERRORINFO) (HGLOBAL, LPSTR);
    
    typedef struct
    {
      LPBDS       lpbdsptr;                // pointer to lpBDS (internal use)
      LPRESULTVAR lprvptr;                 // WIL resultvar (internal use)
      DWORD       dwLevel;                 // feature interface level
      DWORD       dwSize;                  // size of the structure
      DLLSERVICES lpfnDllServices;         // address of DLLServices function
      HGLOBAL     hBatData;                // buffer pointed to by lpBDS
      // feature level 1002+
      HANDLE      hImpersonatedUser;       // handle to impersonated user token
      // feature level 1003+
      HWND        hParentWnd;              // window handle of parent application
      // feature level 1004+
      DLLVARHANDLER    lpfnDllVarHandler;     // address of DllVarHandler function
      DLLARRHANDLER    lpfnDllArrHandler;     // address of DllArrHandler function
      DLLARRAYSERVICES lpfnDllArrayServices;  // address of DllArrayServices function
      // feature level 1005+
      DLLSTOREERRORINFO lpfnDllStoreErrorInfo;  // address of DllStoreErrorInfo function
      // feature level 1006+
      DLLBINARYSERVICES lpfnDllBinaryServices;  // address of DllBinaryServices function
    } VIPERSTRUCT, FAR *LPVIPERSTRUCT;
    
    typedef struct
    {
      DWORD dwDim[5];                      // array dimension sizes
      BYTE  cDims;                         // number of array dimensions
      BYTE  cFlags;                        // array flags
      DWORD dwElements;                    // total number of elements
      DWORD dwDataSize;                    // total size of array data
    } DLLARRAYSERVICES1, FAR *LPDLLARRAYSERVICES1;
    
    typedef int FAR PASCAL ViperCallback (int, LONG, LPVIPERSTRUCT, LPVIPERVAR);
    typedef ViperCallback FAR *LPVIPERCALLBACK;
    
    #ifdef WIN32
    #define DllExport   __declspec(dllexport)
    DllExport LONG
    #else
    LONG
    #endif
    
    FAR PASCAL WILExtender(HWND,
                              HINSTANCE,
                              LONG,
                              short,
                              lpAddOnCallback,
                              LPSTR,
                              LPLONG,
                              LPSTR,
                              LPSTR,
                              LPSTR,
                              LPSTR,
                              LPSTR);
    
    #ifdef WIN32
    #define DllExport   __declspec(dllexport)
    DllExport LONG
    #else
    LONG
    #endif
    
    FAR PASCAL WILExtender2(HWND,
                            HINSTANCE,
                            LONG,
                            short,
                            LPVIPERCALLBACK,
                            LPVIPERSTRUCT,
                            LPLONG,
                            LPVIPERVAR,
                            LONG,
                            LPVIPERVAR);
    
    #ifdef WIN32
    #define DllExport   __declspec(dllexport)
    DllExport LONG
    #else
    LONG
    #endif
    
    FAR PASCAL WILExtenderQuery(short,
                                LPVOID,
                                LONG);
    
    #define COMMEXT_WILSON  0x30030105L
    
    
    //-------------------------------------------------------------------
    // MISC. DEFINITIONS
    //-------------------------------------------------------------------
    #define FUNCTION        2
    #define CONSTANT        3
    #define RESULT_LONG     0
    #define RESULT_STRING   1
    #define RESULT_FLOAT    2
    
    #define RESULT_CALLBACK_ERROR -4
    #define RESULT_FATAL_ERROR    -3
    #define RESULT_MODERATE_ERROR -2
    #define RESULT_MINOR_ERROR    -1
    #define RESULT_SUCCESS         0
    
    //-------------------------------------------------------------------
    //==== DELIMSIZE IS DEFINED BY INTERPRETER, DON'T CHANGE THIS! ======
    //-------------------------------------------------------------------
    #define DELIMSIZE  30
    #define KTDELIMSIZE  30                // Gives us 30 character function names. NO modify
    
    
    //-------------------------------------------------------------------
    // COMMAND EXTENSION STRUCTURES
    //-------------------------------------------------------------------
    typedef struct _COMMEXTSTRUCT {
       short    ident;                     // Our Identifier for item...
       short    type;                      // (2=function,3=constant)
       LONG     param;                     // (funct ? num-args)
                                           // (const ? value)
       short    size;                      // Length of keytoken
       char     delim[DELIMSIZE + 1];      // key token
    } COMMEXTSTRUCT, FAR *LPCOMMEXTSTRUCT;
    
    
    typedef struct tableinfo
    {
      LONG  ident;                         // delimindex - must be consecutive!!!!!!
      LONG  type;                          // 2=FUNCTION 3=CONSTANT 4=COMMAND
      INT64 ulMask;                        // 64-bit mask (16 params, 4 bits each)
      LONG  param1;                        // (funct ? hi(reserved) lo(hibyte(num-optional-args) lobyte(num-required-args)))   (constant ? value)
      short size;                          // length of function name
      char  delim[KTDELIMSIZE + 1];        // funct/const name - must be lowercase!
    } tablestruct, FAR *LPTABLESTRUCT;
    
    
    //-------------------------------------------------------------------
    // Call Back Definitions
    //
    // Parameter - 1 (int)     -3 = Fatal error occured, error string in LPSTR
    //                         -2 = Moderate error occured, error string in LPSTR
    //                         -1 = Minor error occured, error string in LPSTR
    //                          0 = Function suceeded, check BOOL flag to
    //                              see if result is in LPSTR or LONG.
    //                              (RESULT_LONG or RESULT_STRING).
    //
    // Return Values:    Same as first parameter (above), unless the
    //                   callback routine has a problem, like not being
    //                   able allocate storage space... in this case it
    //                   will return -4.
    //
    // NOTE: Return values are to be specified by the 'RESULT_???_ERROR'
    //       definitions under MISC. DEFINITIONS (above).
    //-------------------------------------------------------------------
    int FAR PASCAL COMMEXT_CALLBACK_RTN (int, LONG, LPSTR, BOOL, LONG, LPSTR);
    
    typedef int FAR PASCAL COMMEXT_CALLBACK (int, LONG, LPSTR, BOOL, LONG, LPSTR);
    typedef COMMEXT_CALLBACK FAR *LPCOMMEXT_CALLBACK;
    
    
    //#define MBSS(p1, p2) {MessageBox(GetFocus(), (p2), (p1), MB_OK | MB_SETFOREGROUND);}
    //#define MBSN(p1, p2) {char szDebug[20]; MyLtoa((p2), szDebug, 10); MessageBox(GetFocus(), szDebug, (p1), MB_OK | MB_SETFOREGROUND);}
    
    #endif
    
    
    
    

    Additional conversion tasks

  7. Update help files

    References to 34I in the help file, especially in ALL the AddExtender Lines in the examples should be updated to reflect the new 44I name of the DLL. In most cases simply searching for 34I and replacing that with 44I should do the trick.
  8. README files

    The readme file accompanying the extender should mention the name change and any other relevant items, like the incompatibility with previous version. E.G.

    Ver 12345  Mar 8, 2004
    		The Wampwuzzy extender has been updated to a new
    		format to allow more descriptive function names and
    		additional parameters.  This version of the extender
    		requires	WinBatch 2004B or newer to run.  This
    		extender will not work on WinBatch 2004A or older.
    
    		In addition, so as not to affect existing scripts using
    		a previous version of this extender, the extender DLL
    		has been renamed to include a 44I in the DLL name
    		instead of a 34I.  Old and new versions of this
    		extender can *usually* co-exist side by side.
    
    		To use the new extender with old scripts and with
    		WinBatch 2004B or newer you will need to change the
    		AddExtender line in the script to reflect the new DLL
    		name.   e.g.
    
    		   AddExtender("wwabc34i.dll")
    		should become
    		   AddExtender("wwabc44i.dll")