
29 December 93



PEEKNMP.COM
PEEKNMP.TXT

Key Words: Named Pipes; WinOS2; MS-Access; ODBC; MS-SQL;

This program is a patch which solves some Named Pipe problems in a
WinOS2 session.  Specifically, I was unable to make Microsoft Access
talk via ODBC over Named Pipes to MS-SQL Server over a Novell Netware
network.  The following procedures fixed the problem.

--------------------------------------------------------------------------
How to make MS-Access talk via ODBC over a Named Pipe in a WinOS2 session
--------------------------------------------------------------------------

1. Make sure you are using the latest version of the Novell Netware
   Requester for os2 with the latest patches.
        -- the requester is available via anonymous ftp at HOBBES.NMSU.EDU
           (128.123.35.151) in the /pub/os2/2_x/network directory.  The
           files are called WSOS2_1, WSOS2_2, and WSDRV_1.

        -- download the R201FX.EXE fix from the NOVLIB forum on CompuServe.
           This is a self-extracting compressed file that supplies a number
           of updated drivers for netware.  Copy the files to directories
           according to instructions included in the zip package. (R201FX.EXE
           may also be available at HOBBES.NMSU.EDU).

2. Modify the OS2VER file which is in the root directory of your OS2 boot
   drive.
        -- OS2VER is a hidden, read-only, system file so before you can
           edit it, change these attributes by typing
               ATTRIB -H -S -R OS2VER

           Use any text editor to add the following lines to this file:
               20=NMPIPE.SYS              (note no spaces around = sign)
               20=NPSERVER.SYS
               20=NPDAEMON.EXE

           Reset the attributes on this file by typing
               ATTRIB +H +S +R OS2VER

        -- The above changes are described in the README file which OS2
           creates on the boot drive at install time (look in the root or
           \os2\book directories).

3. Make sure that you've enabled Named Pipes support when the Novell Netware
   requester was installed.

        -- When you install the requester, if you don't indicate that you
           want named pipes support, all files are copied anyway but the
           named-pipe-related statements are REMarked out in your CONFIG.SYS
           file.  Remove the REM from the beginning of these statements.

        -- Make sure you have the appropriate named-pipe statements in your
           NET.CFG file.  (The following are default values; the values you
           need to use may be different.  Use your Netware INSTALL program
           for descriptions & explanations of what these statements do.)

                NAMED PIPES
                  CLIENT SESSIONS   16
                  SERVER SESSIONS   32
                  SERVICE THREADS    3

        -- Make sure that you have appropriate versions of the NETAPI.DLL
           file in the correct places.  That means that the NETAPI.DLL file
           from the \requestr directory on your Novell diskettes should be
           in the \netware directory on your hard drive.  Also, the NETAPI.DLL
           file from the \windows directory of your Novell diskettes should
           be in the \os2\mdos\winos2\system directory on your hard drive.

           (NOTE: in the documentation for MS-SQL Server, it recommends that
           you put the NETAPI.DLL file from the \SQL directory of your Novell
           diskettes in the \netware directory on your hard drive.  I don't
           recommend this, because this NETAPI.DLL causes problems in other
           applications, such as Lotus Notes for OS2.  The NETAPI.DLL from
           the \requestr directory has worked well for me and keeps all the
           other apps on my machine happy.)

4. Set up a separate Winos2 object on your os2 machine that uses a separate
   AUTOEXEC.BAT file.  (I call mine AUTOSQL.BAT).  This file needs to load
   PEEKNMP.COM. (PEEKNMP.COM should have been in the same zip package as the
   file that you are reading now.  If not, look for it on HOBBES.NMSU.EDU as
   mentioned above).

        -- Set up AUTOSQL.BAT so that it loads the following two programs
           when it runs:
           c:\os2\mdos\winos2\TBMI2.COM      (this program comes with os2)
           c:\os2\mdos\winos2\PEEKNMP.COM    (comes in this zip package)


5. Install MS-Access from this WinOS2 session.  This requires patching the
   STFSETUP.INF program on the MS-Access Setup diskette.

        -- The Install program for MS-Access has a bug in it that causes
           the install to fail under certain conditions on a regular
           DOS/Windows 3.1 machine, as well as in a Winos2 session.  These
           problems are documented and can be downloaded from the Microsoft
           KnowledgeBase forum on CompuServe (report number Q102230).

        -- I will explain briefly what you need to do here:
             a) make a backup diskette of your MS-Access Setup Diskette 1.
             b) On the backup disk, use an editor to modify the STFSETUP.IN_
                file.

                Change the [System Paths| section from

                [System Paths|
                SYSTEMPATH = "" ? DETCMD.DLL GetWindowsSysDir
                WINDOWSPATH = "" ? DETCMD.DLL GetWindowsDir
                HARDDRIVELIST  = "" ? DETCMD.DLL GetAllValidLocalHardDrives
                NETDRIVELIST = "" ? DETCMD.DLL GetAllValidNetworkDrives

                to

                [System Paths|
                SYSTEMPATH = "" ? DETCMD.DLL GetWindowsSysDir
                WINDOWSPATH = "" ? DETCMD.DLL GetWindowsDir
                HARDDRIVELIST = "" ? DETCMD.DLL GetAllValidLocalHardDrives
                NETDRIVELIST = "" ? DETCMD.DLL GetAllValidNetworkDrives
                WINDOWSMODE = "" ? DETCMD.DLL GetWindowsMode

                Then change the following

                DoShareStuff = +
                  set CurrentDialog = DoShareStuff
                  set MAKEBAK = "NO"
                  ui start VSHARERunning
                ifstr $(ANSWER) == "NO"

                to

                DoShareStuff = +
                  set CurrentDialog = DoShareStuff
                  set MAKEBAK = "NO"
                ifstr $(WINDOWSMODE) != "ENHANCED"
                  set ANSWER = "NO"
                else
                  ui start VSHARERunning
                endif
                  ifstr $(ANSWER) == "NO"


6. After you have successfully loaded MS-Access, install the ODBC software.
   This install should proceed with no problems.

        -- Install the ODBC Administrator program (ODBCADM.EXE) so that you
           can set up ODBC database sources.

7. Finished !  You should be up and running at this point.  When you start
   the ODBC Adminstrator, you should be able to click on the [Servers] listbox
   and see the names of your Named Pipe servers out on the network.  You
   should also be able to start MS-Access and attach a database table from
   the SQL Server to a local Access database.

8. If you have problems, check that the following files are in the correct
   directories
        -- See number 3 above to make sure you have the right NETAPI.DLLs
           in the right places.

        -- the files DBNMP3.DLL, SQLSERVR.DLL, and W3DBLIB.DLL should be
           in your \os2\mdos\winos2\system directory.

        -- if you still can't figure it out, drop me an Email: my internet
           address is gorvis@nas.edu  (I suffered much when I was trying to
           solve this problem and my experiences may possibly help decrease
           your suffering).




--------------------------------------------------------------------------
More details on the PEEKNMP.COM patch file
--------------------------------------------------------------------------

For those programmer-types who are interested, I have disassembled
and done some homework on the PEEKNMP.COM patch file which enables
MS-Access to use ODBC/Named Pipes in a WinOS2 session.

As far as I can tell, this is a terminate-and-stay-resident (TSR) program
that does one little simple thing: it checks to see if you're calling DOS
function 0x5F, and if you are, it zeroes out the Code Segment (CS)
register before calling DOS to execute that function.  I was unable
to find out what function 0x5F does -- my references just say it is
"reserved."

The way it works is this: the IBM PC ROM BIOS keeps a table of pointers
to functions in low memory.  One of those functions is the "DOS Call"--
in other words, DOS has all these utilities built into it, and
you "get at" them by putting your parameters in certain registers, and
then generating software interrupt 0x21, which calls the routine which
is pointed to from that place in low memory.

What this program does is change that pointer to point at its own code --
which checks for function 0x5F -- after which it calls the original
DOS function.  If you're *not* calling function 5F, it doesn't do
anything -- it just calls the original DOS interrupt.


---------------------------------------------------------------------------
   PEEKNMP.COM  disassembled
---------------------------------------------------------------------------


D:\>  debug peeknmp.com

-u 0100


1518:0100 90            NOP                     ; No operation
1518:0101 EB3B          JMP     013E            ; Jump to 013E


; ------------------------------- This is the "hook" - code that gets -------
                                     executed before calling the original
                                     DOS routine

1518:0103 0000          ADD     [BX+SI],AL      ; These are stored zeroes,
1518:0105 0000          ADD     [BX+SI],AL      ;   not instructions (?)

1518:0107 EB10          JMP     0119            ; Whenever a program calls DOS
                                                ;   function 0x21, execution
                                                ;   will jump to this line of
                                                ;   our program -- which then
                                                ;   jumps to line 0119.

1518:0109 0000          ADD     [BX+SI],AL      ; These two lines start out
1518:010B 0000          ADD     [BX+SI],AL      ;   empty, but this is where
                                                ;   the address of DOS function
                                                ;   0x21 will be stored

1518:010D 4B            DEC     BX              ; I don't know what these
1518:010E 42            INC     DX              ;   instructions do
1518:010F 00EB          ADD     BL,CH           ;
1518:0111 00CB          ADD     BL,CL           ;
1518:0113 0000          ADD     [BX+SI],AL
1518:0115 0000          ADD     [BX+SI],AL
1518:0117 0000          ADD     [BX+SI],AL


1518:0119 3D355F        CMP     AX,5F35         ; Compare AX register w/0x5F35
1518:011C 7405          JZ      0123            ;   If they are equal, jump
                                                ;   to line 0123.

1518:011E 2E            CS:                     ; If they're not equal, pass
1518:011F FF2E0901      JMP     FAR [0109]      ;   thread of execution back to
                                                ;   the original DOS function

1518:0123 2E            CS:                     ; AX equalled 0x5F35, so we
1518:0124 8F060301      POP     [0103]          ;   come here.  These lines
1518:0128 2E            CS:                     ;   stick whatever's in lines
1518:0129 8F060501      POP     [0105]          ;   0103 and 0105 of our program
1518:012D 2E            CS:                     ;   into the CS register.

1518:012E FF1E0901      CALL    FAR [0109]      ; And then it calls the original
                                                ;   DOS function which handles
                                                ;   interrupt 0x21.

1518:0132 7205          JB      0139            ; I don't know what this stuff
1518:0134 8BF8          MOV     DI,AX           ;   does (maybe never gets
1518:0136 B80000        MOV     AX,0000         ;   executed)...?
1518:0139 2E            CS:
1518:013A FF2E0301      JMP     FAR [0103]



; ----------------------------------------  Where the program starts -----

1518:013E B82135        MOV     AX,3521         ; This calls the DOS function
                                                ;   to request the address of
                                                ;   the interrupt vector for
                                                ;   DOS function Ox21, which
                                                ;   my reference says "invokes
                                                ;   all function-call services
                                                ;   in DOS."

1518:0141 CD21          INT     21              ; Call DOS to execute the above.
                                                ;   The segment:offset address
                                                ;   of the interrupt handler
                                                ;   will be stored in the ES:BX
                                                ;   register pair.

1518:0143 891E0901      MOV     [0109],BX       ; Here we take the address which
1518:0147 8C060B01      MOV     [010B],ES       ;   is returned by the above
                                                ;   function, and we stick it
                                                ;   into our program at lines
                                                ;   0109 and 010B (Intel ad-
                                                ;   dresses are used backwards).

1518:014B BA0701        MOV     DX,0107         ; Here we get set up to make
1518:014E B82125        MOV     AX,2521         ;   DOS interrupt 0x21 point to
                                                ;   line 0107 of our program
                                                ;   (see above).

1518:0151 CD21          INT     21              ; Call DOS to execute the above
                                                ;   function.

1518:0153 BA4D01        MOV     DX,014D         ; Tell DOS how much memory to
                                                ;   reserve before terminate-
                                                ;   and-stay-resident

1518:0156 B90400        MOV     CX,0004         ; ??? Move 0004 into the CX reg
1518:0159 D3EA          SHR     DX,CL           ; ??? Shift the DX register to
                                                ;   the right by however many
                                                ;   bytes are in CX (4 bytes).

1518:015B B80031        MOV     AX,3100         ; Set up to call the Terminate-
                                                ;   and-stay-resident function
                                                ;   in DOS.

1518:015E CD21          INT     21              ; Call DOS to execute the above
                                                ;   function.


; ---------------------------------------------------------------------------
1518:0160 2020          AND     [BX+SI],AH      ; The remaining bytes in this
1518:0162 2020          AND     [BX+SI],AH      ;   program are all 0x20's ;
1518:0164 2020          AND     [BX+SI],AH      ;   maybe this is just junk
1518:0166 2020          AND     [BX+SI],AH      ;   leftover by the compiler,
1518:0168 2020          AND     [BX+SI],AH      ;   or maybe it's reserving
1518:016A 2020          AND     [BX+SI],AH      ;   space for something.
1518:016C 2020          AND     [BX+SI],AH
1518:016E 2020          AND     [BX+SI],AH
1518:0170 2020          AND     [BX+SI],AH
1518:0172 2020          AND     [BX+SI],AH
1518:0174 2020          AND     [BX+SI],AH
1518:0176 2020          AND     [BX+SI],AH
1518:0178 2020          AND     [BX+SI],AH
1518:017A 2020          AND     [BX+SI],AH
1518:017C 2020          AND     [BX+SI],AH
1518:017E 2020          AND     [BX+SI],AH
1518:0180 2020          AND     [BX+SI],AH
1518:0182 2020          AND     [BX+SI],AH
-
