#include "os2win.h"
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>

HANDLE hinst;
CRITICAL_SECTION HP_cs_mutex;
HANDLE           HP_event_sem;

int main(int argc, char *argv[])
{
    return(0);
}

VOID HP_SetHinst(HANDLE h)
{
    hinst = h;
    return;
}

LONG HP_gpiCharStringAt(HDC hdc, PPOINTL ppl, int cb, LPCSTR pch)
{
    UINT uintSave;
    uintSave = GetTextAlign(hdc);
    SetTextAlign(hdc, uintSave | TA_UPDATECP);
    MoveToEx(hdc, ppl->x, ppl->y, NULL);
    TextOut(hdc, 0, 0, pch, cb);
    SetTextAlign(hdc, uintSave);
    return(TRUE);
}

USHORT HP_dosReallocSeg(USHORT usNew, SEL sel)
{
    UINT cb = LocalSize(sel);

    if ((UINT) usNew > cb)
        MessageBox(NULL, "Cannot Grow memory with cheater libs.",
            "OS/2 conversion Error", MB_ICONHAND | MB_OK);
    return(0);
    
}


USHORT HP_dosFreeSeg( SEL sel)
{
    LocalFree(sel);
    return(0);
}

USHORT HP_dosAllocSeg( USHORT usSize, PSEL psel, USHORT fs)
{
    if (fs & (SEG_GIVEABLE | SEG_GETTABLE))
        MessageBox(NULL, "Give/Get Seg not supported.",
            "OS/2 conversion Error", MB_ICONHAND | MB_OK);

    *psel = LocalAlloc(LPTR, (UINT) usSize);

    return(0);
}

BOOL HP_winQueryCursorInfo(HWND hd, PCURSORINFO pcsri)
{
    POINT ptl;
    GetCursorPos(&ptl);

    pcsri->hwnd = WindowFromPoint(ptl);
    pcsri->x =  ptl.x;
    pcsri->y =  ptl.y;
    pcsri->cx =  0;   // USE Defaults.
    pcsri->cy =  0;
    pcsri->fs = 0;    // CURSOR_SOLID
    GetClipCursor(&pcsri->rclClip);
    return(TRUE);
}



HWND HP_winQueryWindow(HWND hwnd, SHORT cmd, BOOL b)
{
    switch (cmd)
    {
    case QW_NEXT:
        return(GetNextWindow(hwnd, GW_HWNDNEXT));
        break;
    case QW_PREV:
        return(GetNextWindow(hwnd, GW_HWNDPREV));
        break;
    case QW_TOP:
        return(GetTopWindow(hwnd));
        break;
    case QW_BOTTOM:
        return(GetWindow(GetWindow(hwnd,GW_CHILD), GW_HWNDLAST));
        break;
    case QW_OWNER:
        return(GetWindow(hwnd, GW_OWNER));
        break;
    case QW_PARENT:
        return(GetParent(hwnd));
        break;
    case QW_NEXTTOP:
        return(GetWindow(hwnd, GW_HWNDNEXT));
        break;
    case QW_PREVTOP:
        return(GetWindow(hwnd, GW_HWNDPREV));
        break;
    default:
        return(NULL);
        break;
    }
}

HANDLE HP_winQuerySysPointer(HWND hd, SHORT s, BOOL b)
{
    switch(s)
    {
    case SPTR_APPICON:
        LoadIcon(NULL, IDI_APPLICATION);
        break;
    case SPTR_ARROW:
        LoadCursor(NULL, IDC_ARROW);
        break;
    case SPTR_ICONERROR:
        LoadIcon(NULL, IDI_HAND);
        break;
    case SPTR_ICONINFORMATION:
        LoadIcon(NULL, IDI_ASTERISK);
        break;
    case SPTR_ICONQUESTION:
        LoadIcon(NULL, IDI_QUESTION);
        break;
    case SPTR_ICONWARNING:
        LoadIcon(NULL, IDI_EXCLAMATION);
        break;
    case SPTR_MOVE:
        MessageBox(NULL, "No SPTR_MOVE ICON in Windows",
            "OS/2 conversion Error", MB_ICONHAND | MB_OK);
        return(NULL);
        break;
    case SPTR_SIZENESW:
        LoadCursor(NULL, IDC_SIZENESW);
        break;
    case SPTR_SIZENS:
        LoadCursor(NULL, IDC_SIZENS);
        break;
    case SPTR_SIZENWSE:
        LoadCursor(NULL, IDC_SIZENWSE);
        break;
    case SPTR_SIZEWE:
        LoadCursor(NULL, IDC_SIZEWE);
        break;
    case SPTR_TEXT:
        LoadCursor(NULL, IDC_IBEAM);
        break;
    case SPTR_WAIT:
        LoadCursor(NULL, IDC_WAIT);
        break;
    }
}

USHORT HP_dosChgFilePtr(HANDLE h, LONG l, USHORT M, PULONG pul)
{
    DWORD dw;
    dw = SetFilePointer(h, l, NULL, M);
 
    if (pul) 
        *pul = SetFilePointer(h, l, NULL, M);
    return( (dw) ? 0 : -1);
}

VOID HP_dosExit( USHORT usF, USHORT usC)
{
    if (usF == EXIT_THREAD)
        ExitThread(usC);

    MessageBox(NULL, "Exited Process with DosExit",
        "Poss. OS/2 conversion Error", MB_ICONHAND | MB_OK);
    ExitProcess(usC);
}

USHORT HP_dosQHandType( HANDLE h, PULONG pul, PUSHORT pus)
{
    DWORD dw = GetFileType(h);

    if (pul) 
        *pul = dw;
    return( (dw) ? 0 : -1);
}

USHORT HP_dosQFileMode( PSZ psz, PULONG pul, DWORD d)
{
    DWORD dw = GetFileAttributes(psz);

    if (pul) 
        *pul = dw;
    return( (dw) ? 0 : -1);
}

USHORT HP_dosGetProcAddress( HANDLE h, PSZ psz, PPFN pul)
{
    FARPROC dw = GetProcAddress(h, psz);

    if (pul) 
        *pul = dw;
    return( (dw) ? 0 : -1);
}

DWORD HP_dosMakeNmPipe(PSZ pszName, PHPIPE php, USHORT fsOpenMode,
    USHORT fsPipeMode, USHORT cbOutBuf, USHORT cbInBuf, DWORD ulTimeOut)
    {
    *php = CreateNamedPipe( pszName, fsOpenMode, fsPipeMode,
        1L, cbOutBuf, cbInBuf, ulTimeOut, NULL);
    if (*php != NULL)
        return(0);
    else
        return(GetLastError());
    }

DWORD HP_dosOpen(PSZ pszFileName, PHANDLE phf, PUSHORT pusAction,
    ULONG ulFileSize, USHORT usAttribute, USHORT fsOpenFlags, 
    USHORT fsOpenMode, ULONG ul)
    {
    DWORD fdwAccess, fdwShareMode, fdwCreate, fdwAttr;
    USHORT usTmp;
    SECURITY_ATTRIBUTES sa;

    fdwAccess = fdwShareMode = fdwCreate = 0L;

    if (fsOpenFlags == FILE_CREATE)   fdwAccess = CREATE_NEW;
    if (fsOpenFlags == FILE_OPEN)     fdwAccess = OPEN_EXISTING;
    if (fsOpenFlags == FILE_TRUNCATE) fdwAccess = TRUNCATE_EXISTING;

    if (fsOpenFlags == (FILE_CREATE | FILE_TRUNCATE)) 
        fdwAccess = CREATE_ALWAYS;

    if (fsOpenFlags == (FILE_CREATE | FILE_OPEN)) 
        fdwAccess = OPEN_ALWAYS;

    if (fsOpenMode & OPEN_ACCESS_WRITEONLY) 
        fdwAccess = GENERIC_WRITE;
    else if (fsOpenMode & OPEN_ACCESS_READWRITE) 
        fdwAccess = GENERIC_WRITE | GENERIC_READ;
    else
        fdwAccess = GENERIC_READ;

    fdwAttr = (DWORD) usAttribute;
    if (fsOpenMode & OPEN_FLAGS_WRITE_THROUGH)
        fdwAttr |= FILE_FLAG_WRITE_THROUGH;
    if (fsOpenMode & OPEN_FLAGS_NO_CACHE)
        fdwAttr |= FILE_FLAG_NO_BUFFERING;
    if (fsOpenMode & OPEN_FLAGS_SEQUENTIAL)
        fdwAttr |= FILE_FLAG_SEQUENTIAL_SCAN;
    if (fsOpenMode & OPEN_FLAGS_RANDOM)
        fdwAttr |= FILE_FLAG_RANDOM_ACCESS;

    usTmp = fsOpenMode & 0x0070;
    if (usTmp == OPEN_SHARE_DENYREAD)  fdwShareMode = FILE_SHARE_WRITE;
    if (usTmp == OPEN_SHARE_DENYWRITE) fdwShareMode = FILE_SHARE_READ;
    if (usTmp == OPEN_SHARE_DENYNONE)  
        fdwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;

    sa.nLength              = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    if (fsOpenMode & OPEN_FLAGS_NOINHERIT)
        sa.bInheritHandle = FALSE;
    else
        sa.bInheritHandle = TRUE;

    *phf = CreateFile( pszFileName, fdwAccess, fdwShareMode,
            &sa, fdwCreate, fdwAttr, NULL);
    if (*phf != NULL)
        return(0);
    else
        return(GetLastError());
    }

USHORT HP_dosQCurDir(USHORT usDriveNum, PSZ pszPath, PUSHORT pcb)
{
    char chCurrent[MAX_PATH], chOther[MAX_PATH];
    char ch;
    USHORT usCurrent;

    GetCurrentDirectory(MAX_PATH, chCurrent);
    ch = toupper(chCurrent[0]);
    usCurrent = (char) ((0x007F & ch) - (0x007F & 'A') + 1);
    if (usDriveNum == 0 || usDriveNum == usCurrent)
        strcpy( chOther, chCurrent);
    else
        {
        strcpy( chOther, "A:");
        ch = usDriveNum + (0x007F & 'A') - 1;
        chOther[0] = ch;
        SetCurrentDirectory(chOther);
        GetCurrentDirectory(MAX_PATH, chOther);
        SetCurrentDirectory(chCurrent);
        }

    if ((strlen(chOther) - 1) > *pcb)
        return(ERROR_BUFFER_OVERFLOW);
    else
        {
        strcpy( pszPath, &chOther[2]);
        return(0);
        }
}

USHORT HP_dosQCurDisk(PUSHORT pusDriveNum, PULONG pul)
{
    char chCurrent[MAX_PATH];
    char ch;

    GetCurrentDirectory(MAX_PATH, chCurrent);
    ch = toupper(chCurrent[0]);
    *pusDriveNum = (0x007F & ch) - (0x007F & 'A') + 1;
    *pul = GetLogicalDrives();
    return(0);

    
}

USHORT HP_dosSelectDisk(USHORT usDriveNum)
{
    char chOther[MAX_PATH];
    char ch;

    strcpy( chOther, "A:");
    ch = (char)(usDriveNum + (0x007F & 'A') - 1);
    chOther[0] = ch;
    SetCurrentDirectory(chOther);
    return(0);
}

HFONT HP_SimpleFont( LPCTSTR szFaceName, LONG size, LONG width, DWORD fs)
{
    LOGFONT lf;
    lf.lfHeight = size;
    lf.lfWidth = width;
    lf.lfEscapement = 0;
    lf.lfOrientation  = 0;
    lf.lfWeight = (fs & FATTR_SEL_BOLD) ? FW_BOLD : FW_NORMAL;
    lf.lfItalic = (fs & FATTR_SEL_ITALIC) ? TRUE : FALSE;
    lf.lfUnderline = (fs & FATTR_SEL_UNDERSCORE) ? TRUE : FALSE;
    lf.lfStrikeOut = (fs & FATTR_SEL_STRIKEOUT) ? TRUE : FALSE;
    lf.lfCharSet = ANSI_CHARSET;
    lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
    lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
    lf.lfQuality       = DEFAULT_QUALITY;
    lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
    
    strcpy( lf.lfFaceName, szFaceName);

	 return(CreateFontIndirect(&lf));

}

void HP_RegisterClass(LPCTSTR pszClassName, PFN pfn, DWORD fs, int cb)
    {
    WNDCLASS wc;
	 ATOM     aClass;

    wc.lpfnWndProc   = (WNDPROC) pfn;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = cb;
    wc.hInstance     = hinst;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE + 1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = pszClassName;
    wc.style         = 0;
    wc.style        |= (fs & HP_CS_SAVEBITS) ? CS_SAVEBITS : 0;
    wc.style        |= (fs & HP_CS_SIZEREDRAW) ? (CS_HREDRAW | CS_VREDRAW) : 0;

	 aClass = RegisterClass(&wc);
	 if (aClass == 0x0000)
		  fprintf( stderr, "RegisterClass Failure! \n" );

    }

HWND HP_CreateStdWindow(HWND hwndParent, DWORD flStyle1, LPDWORD pflStyle2,
    LPCTSTR pszClass, LPCTSTR pszTitle, DWORD flStyle3, HMODULE hmod,
    DWORD lpv, PHWND phwndClient)
    {
    DWORD dwStyle = 0;
    HWND  hwnd;
	 DWORD flStyle2 = (pflStyle2) ? *pflStyle2 : 0;
	 HMENU hMenu;

    flStyle1 |= flStyle3;
    dwStyle |= (flStyle1 & HP_FS_DLGBORDER ) ? WS_BORDER : 0;
    dwStyle |= (flStyle1 & HP_FS_BORDER ) ? WS_BORDER : 0;
    dwStyle |= (flStyle1 & HP_FS_SIZEBORDER ) ? WS_THICKFRAME : 0;
    dwStyle |= (flStyle1 & HP_FS_STANDARD ) ? WS_OVERLAPPEDWINDOW : 0;
    dwStyle |= (flStyle1 & HP_WS_VISIBLE ) ? WS_VISIBLE : 0;
    dwStyle |= (flStyle1 & HP_WS_DISABLED ) ? WS_DISABLED : 0;
    dwStyle |= (flStyle1 & HP_WS_CLIPCHILDREN ) ? WS_CLIPCHILDREN : 0;
    dwStyle |= (flStyle1 & HP_WS_CLIPSIBLINGS ) ? WS_CLIPSIBLINGS : 0;
    dwStyle |= (flStyle1 & HP_WS_MINIMIZED ) ? WS_MINIMIZE : 0;
    dwStyle |= (flStyle1 & HP_WS_MAXIMIZED ) ? WS_MAXIMIZE : 0;
    dwStyle |= (flStyle1 & HP_WS_GROUP ) ? WS_GROUP : 0;
    dwStyle |= (flStyle1 & HP_WS_TABSTOP ) ? WS_TABSTOP : 0;
    dwStyle |= (flStyle2 & HP_FCF_TITLEBAR ) ? WS_CAPTION : 0;
    dwStyle |= (flStyle2 & HP_FCF_SYSMENU ) ? WS_SYSMENU : 0;
    dwStyle |= (flStyle2 & HP_FCF_SIZEBORDER ) ? WS_THICKFRAME : 0;
    dwStyle |= (flStyle2 & HP_FCF_MINBUTTON ) ? WS_MINIMIZEBOX : 0;
    dwStyle |= (flStyle2 & HP_FCF_MAXBUTTON ) ? WS_MAXIMIZEBOX : 0;
    dwStyle |= (flStyle2 & HP_FCF_VERTSCROLL ) ? WS_VSCROLL : 0;
    dwStyle |= (flStyle2 & HP_FCF_HORZSCROLL ) ? WS_HSCROLL : 0;
    dwStyle |= (flStyle2 & HP_FCF_DLGBORDER ) ? WS_BORDER : 0;
    dwStyle |= (flStyle2 & HP_FCF_BORDER ) ? WS_BORDER : 0;
    dwStyle |= (flStyle2 & HP_FCF_STANDARD ) ? WS_OVERLAPPED : 0;

	 hMenu = LoadMenu(hinst, MAKEINTRESOURCE(lpv));

	 try {
		 hwnd = CreateWindow(pszClass, pszTitle, dwStyle, CW_USEDEFAULT,
						 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
						 hwndParent, hMenu, hinst, NULL);
		  }
	 except( EXCEPTION_EXECUTE_HANDLER)
	 	  {
		  fprintf( stderr, "CreateWindow Exception %ld\n", GetExceptionCode());
		  }

    if (phwndClient)
        *phwndClient = hwnd;

    return(hwnd);
    }

UINT HP_Message(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2, UINT fSend)
{
    WPARAM wParam = mp1;
    LPARAM lParam = mp2;
    UINT   uRet;

    switch(msg)
        {
        case WM_SETICON:
            SetClassLong(hwnd, GCL_HICON, mp1);
            return(TRUE);
            break;
        case HP_SBM_SETPOS:
            // Assume Vertical scroll bar.
            SetScrollPos(hwnd, SB_VERT, LOWORD(mp1), TRUE);
            return(TRUE);
            break;
        case HP_SBM_SETSCROLLBAR:
            SetScrollRange(hwnd, SB_VERT, LOWORD(mp2), HIWORD(mp2), FALSE);
            SetScrollPos(hwnd, SB_VERT, LOWORD(mp1), TRUE);
            return(TRUE);
            break;
        case HP_SBM_QUERYPOS:
            return(GetScrollPos(hwnd, SB_VERT));
        case HP_SBM_QUERYRANGE:
            {
            DWORD dwLow, dwHigh;
            GetScrollRange(hwnd, SB_VERT, &dwLow, &dwHigh);
            return(MAKELONG(LOWORD(dwLow),LOWORD(dwHigh)));
            }
        case WM_CHAR:
            {
            PACKED_LONG pl;

            pl.dw = 0;

            wParam = 0x000000FF & CHAR1FROMMP(mp2);
            pl.shl = CHAR3FROMMP(mp1);
            pl.ch[2] = CHAR4FROMMP(mp1);
            lParam = pl.dw;
            }
            break;

        case MM_SETITEMATTR:
            {
            USHORT idItem  = LOWORD(mp1);
            USHORT usChg   = LOWORD(mp2);
            USHORT usFlags = HIWORD(mp2);

            if (usChg & HP_MIA_CHECKED)
                {
                CheckMenuItem(GetMenu(hwnd), idItem, 
                    (usFlags & HP_MIA_CHECKED) ? MF_CHECKED : MF_UNCHECKED);
                }
            if (usChg & HP_MIA_HILITED)
                {
                HiliteMenuItem(hwnd, GetMenu(hwnd), idItem, 
                    (usFlags & HP_MIA_HILITED) ? MF_HILITE : MF_UNHILITE);
                }
            if (usChg & HP_MIA_DISABLED)
                {
                CheckMenuItem(GetMenu(hwnd), idItem, 
                    (usFlags & HP_MIA_DISABLED) ? (MF_DISABLED | MF_GRAYED)
                        : MF_ENABLED);
                }
            }
            break;
        default:
            break;
        }

    if (fSend)
        uRet = SendMessage(hwnd,msg,wParam,lParam);
    else
        uRet = PostMessage(hwnd,msg,wParam,lParam);

    return(uRet);
}

UINT HP_DlgItemMessage(HWND hwnd, int idDlg, UINT msg, WPARAM mp1, LPARAM mp2)
{
    WPARAM wParam = mp1;
    LPARAM lParam = mp2;
    UINT   uRet;

    switch(msg)
        {
        case HP_LB_GETTEXT:
            wParam = LOWORD(mp1);
            break;
        case HP_BM_GETSTATE:   // They just want the hilite!
            {
            UINT uState = SendDlgItemMessage(hwnd,idDlg,msg,wParam,lParam);
            return((uState & 0x0004) ? TRUE : FALSE);
            }
        case HP_EM_GETMODIFY:
            uRet = SendDlgItemMessage(hwnd,idDlg,msg,0,0);
            SendDlgItemMessage(hwnd,idDlg, EM_SETMODIFY, FALSE, 0);
            return(uRet);
        case HP_EM_GETSEL:
            {
            DWORD dwLow, dwHigh;

            SendDlgItemMessage(hwnd,idDlg,msg,(DWORD)&dwLow,(DWORD)&dwHigh);
            return(MAKELONG(LOWORD(dwLow),LOWORD(dwHigh)));
            }
        case HP_EM_SETSEL:
            wParam = LOWORD(mp1);
            lParam = HIWORD(mp1);
            break;

        case HP_MLM_QUERYSEL:
            {
            DWORD dwLow, dwHigh;
            SendDlgItemMessage(hwnd,idDlg,msg,(DWORD)&dwLow,(DWORD)&dwHigh);
            switch( mp1)
                {
                case MLFQS_MINMAXSEL:
                    return(MAKELONG(LOWORD(dwLow),LOWORD(dwHigh)));
                case MLFQS_CURSORSEL: // Incorrect, but we'll live.
                case MLFQS_ANCHORSEL:
                case MLFQS_MINSEL:
                    return(dwLow);
                case MLFQS_MAXSEL:
                    return(dwHigh);
                default:
                    return(0);

                }
            }
            break;

        case HP_LB_SELITEMRANGE:
            wParam = mp2;
            lParam = MAKELONG(LOWORD(mp1),LOWORD(mp1));
            break;

        case HP_LM_SETITEMTEXT:
            SendDlgItemMessage(hwnd,idDlg,LB_DELETESTRING,LOWORD(mp1),0);
            SendDlgItemMessage(hwnd,idDlg,LB_INSERTSTRING,LOWORD(mp1),0);
            return(TRUE);

        default:
            break;
        }

    uRet = SendDlgItemMessage(hwnd,idDlg,msg,wParam,lParam);

    return(uRet);
}


int HP_IsPtr( LPVOID lpv)
{
    char ch;
    int  bPtr = TRUE;

    try
        {
        ch = *((char *) lpv);
        }
    except (EXCEPTION_EXECUTE_HANDLER)
        {
        bPtr = FALSE;
        }

    return(bPtr);
}

#define HP_RAM_SEM(lpv) ((LPDWORD)(lpv))
#define HP_VALID_RAM_SEM(lpv) (*(HP_RAM_SEM(lpv)) == 0 || *(HP_RAM_SEM(lpv)) == 1)

DWORD HP_dosCreateSem(int bExclusive, LPHANDLE lph, LPCTSTR lpch)
{
    char chName[256];

    strcpy( chName, "sem_");

    lpch += 5;  // Skip over leading "\sem\"

    strcat( chName, lpch);
    *lph = CreateSemaphore(NULL, 1, 1, chName);

    return( (*lph) ? 0 : GetLastError());
}


DWORD HP_dosOpenSem( LPHANDLE lph, LPCTSTR lpch, DWORD dwAccess)
{
    char chName[256];

    strcpy( chName, "sem_");

    lpch += 5;  // Skip over leading "\sem\"

    strcat( chName, lpch);
    *lph = OpenSemaphore(dwAccess, TRUE, chName);

    return( (*lph) ? 0 : GetLastError());
}

USHORT HP_dosSemClear(HANDLE lpv)
{
    DWORD dw;
    if (HP_IsPtr((LPVOID)lpv) && HP_VALID_RAM_SEM(lpv))
        {
        EnterCriticalSection(&HP_cs_mutex);
        dw = *(HP_RAM_SEM(lpv));
        *(HP_RAM_SEM(lpv)) = 1;
        if (dw != 1)
            {
            // This should release all waiting threads
            SetEvent(HP_event_sem);

            // Reclose the door.  I assume everyone is free.
            ResetEvent(HP_event_sem);
            }
        LeaveCriticalSection(&HP_cs_mutex);
        return(0);
        }

}

USHORT HP_dosSemSet(HANDLE lpv)
{
    if (HP_IsPtr((LPVOID)lpv) && HP_VALID_RAM_SEM(lpv))
        {
        EnterCriticalSection(&HP_cs_mutex);
        *(HP_RAM_SEM(lpv)) = 0;
        LeaveCriticalSection(&HP_cs_mutex);
        return(0);
        }

}


USHORT HP_dosSemWait(HANDLE lpv, DWORD lTimeOut)
{
    DWORD dw;
    DWORD dwRet;
    DWORD dwRet2;

    if (HP_IsPtr((LPVOID)lpv) && HP_VALID_RAM_SEM(lpv))
        {
        EnterCriticalSection(&HP_cs_mutex);
        dw = *(HP_RAM_SEM(lpv));
        while (dw == 0)
            {
            LeaveCriticalSection(&HP_cs_mutex);

            // Warning, timeout reset on every loop!
            dwRet = WaitForSingleObject(HP_event_sem, lTimeOut);
            if (dwRet)
                return((USHORT) dwRet);

            EnterCriticalSection(&HP_cs_mutex);
            dw = *(HP_RAM_SEM(lpv));
            }


        LeaveCriticalSection(&HP_cs_mutex);
        return(0);
        }

    else
        {
        do
            {
            dwRet  = WaitForSingleObject(lpv, lTimeOut);
            dwRet2 = ReleaseSemaphore(lpv, 1, NULL);
            } while (dwRet2 == FALSE);
        }
}


USHORT HP_dosSemRequest(HANDLE lpv, DWORD lTimeOut)
{
    DWORD dw;
    DWORD dwRet;

    if (HP_IsPtr((LPVOID)lpv) && HP_VALID_RAM_SEM(lpv))
        {
        EnterCriticalSection(&HP_cs_mutex);
        dw = *(HP_RAM_SEM(lpv));
        while (dw == 0)
            {
            LeaveCriticalSection(&HP_cs_mutex);

            // Warning, timeout reset on every loop!
            dwRet = WaitForSingleObject(HP_event_sem, lTimeOut);
            if (dwRet)
                return((USHORT) dwRet);

            EnterCriticalSection(&HP_cs_mutex);
            dw = *(HP_RAM_SEM(lpv));
            }

        *(HP_RAM_SEM(lpv)) = 0;

        LeaveCriticalSection(&HP_cs_mutex);
        return(0);
        }
    else
        {
        return((USHORT) WaitForSingleObject(lpv, lTimeOut));
        }

}

#define MAX_SEARCH 16

int iNumSearches = -1;
typedef struct _ff
    {
    HANDLE  hSearch;
    DWORD   dwAttr;
    } HP_FIND;

HP_FIND hp_fSearches[MAX_SEARCH + 1];


DWORD HP_dosFindFirst(LPTSTR pszSpec, LPDWORD ph, USHORT usAttr,
    LPWIN32_FIND_DATA lpdata, USHORT usBufLen, PUSHORT pusCount)
{

    int iCreate = (int) *ph;
    HANDLE hFind;
    DWORD  dwAttr = (DWORD) usAttr;
    int    iMax = *pusCount;
    int    ii = 0;
    BOOL   bOk = TRUE;


    if (iNumSearches == -1)
        {
        for (ii = 0; ii < (MAX_SEARCH + 1); ii++)
            hp_fSearches[ii].hSearch = NULL;
        ii = 0;
        iNumSearches = 0;
        }


    if (sizeof(WIN32_FIND_DATA) * iMax > (DWORD) usBufLen)
        iMax = usBufLen / sizeof(WIN32_FIND_DATA);

    if (iCreate == HDIR_SYSTEM && hp_fSearches[MAX_SEARCH].hSearch != NULL)
        {
        CloseHandle(hp_fSearches[MAX_SEARCH].hSearch);
        hp_fSearches[MAX_SEARCH].hSearch = NULL;
        }
    else if ( iNumSearches == MAX_SEARCH)
        {
        return(0xFFFF);  // SHOULD be ERROR_NO_MORE_SEARCH_HANDLES
        }


    if (dwAttr == 0)
        dwAttr = FILE_ATTRIBUTE_NORMAL;

    hFind = FindFirstFile( pszSpec, lpdata);

    if (hFind == NULL)
        return(GetLastError());

    while (bOk && (ii < iMax))
        {
        if (lpdata->dwFileAttributes & dwAttr)
            {
            ii++;
            lpdata++;
            }


        bOk = FindNextFile (hFind, lpdata);
        if (bOk == FALSE && GetLastError() == ERROR_NO_MORE_FILES
            && ii == 0)
            return(ERROR_NO_MORE_FILES);

        }

    *pusCount = ii;

    if (iCreate == HDIR_SYSTEM)
        {
        hp_fSearches[MAX_SEARCH].hSearch = hFind;
        hp_fSearches[MAX_SEARCH].dwAttr  = dwAttr;
        *ph = MAX_SEARCH;
        }
    else
        {
        for (ii = 0; ii < MAX_SEARCH &&
            hp_fSearches[ii].hSearch != NULL; ii++) ;

        hp_fSearches[ii].hSearch = hFind;
        hp_fSearches[ii].dwAttr  = dwAttr;
        *ph = ii;
        iNumSearches++;
        }

    return(0);

}

USHORT HP_dosFindNext(DWORD dw, LPWIN32_FIND_DATA lpdata,
        USHORT usBufLen, PUSHORT pusCount)
{

    HANDLE hFind;
    DWORD  dwAttr;
    int    iMax = *pusCount;
    int    ii = 0;
    BOOL   bOk = TRUE;

    if (sizeof(WIN32_FIND_DATA) * iMax > (DWORD) usBufLen)
        iMax = usBufLen / sizeof(WIN32_FIND_DATA);


    if (dw < 0 || dw > (MAX_SEARCH + 1))
        return(ERROR_INVALID_HANDLE);

    hFind  = hp_fSearches[dw].hSearch;
    dwAttr = hp_fSearches[dw].dwAttr;

    do
        {
        bOk = FindNextFile (hFind, lpdata);
        if (bOk == FALSE && GetLastError() == ERROR_NO_MORE_FILES
            && ii == 0)
            return(ERROR_NO_MORE_FILES);

        if (lpdata->dwFileAttributes & dwAttr)
            {
            ii++;
            lpdata++;
            }

        } while (bOk && (ii < iMax));


    *pusCount = ii;

    return(0);

}

USHORT HP_dosFindClose(DWORD dw)
{
    if (dw < 0 || dw > (MAX_SEARCH + 1))
        return(ERROR_INVALID_HANDLE);

    CloseHandle(hp_fSearches[dw].hSearch);
    hp_fSearches[dw].hSearch = NULL;

    if (dw != MAX_SEARCH)
        iNumSearches--;

    return(0);

}

DWORD HP_dosNewSize(HANDLE h, DWORD dwSize)
{
    DWORD dwCurrent;

    dwCurrent = SetFilePointer(h, 0, NULL, FILE_CURRENT);
    if (dwCurrent == NEG_ONE)
        return(GetLastError());

    SetFilePointer(h, dwSize, NULL, FILE_CURRENT);
    SetEndOfFile(h);
    SetFilePointer(h, dwCurrent, NULL, FILE_BEGIN);
    return(0);
}

DWORD HP_dosFileLocks(HANDLE h, PFILELOCK pfUnlock, PFILELOCK pfLock)
{
    BOOL bOk = TRUE;

    if (pfUnlock)
        bOk = UnlockFile(h, pfUnlock->lOffset, 0, pfUnlock->lRange, 0);

    if (bOk == FALSE)
        return(GetLastError());

    if (pfLock)
        bOk = LockFile(h, pfLock->lOffset, 0, pfLock->lRange, 0);

    if (bOk == FALSE)
        return(GetLastError());

    return(0);

}

DWORD HP_dosMakePipe( LPHANDLE lpR, LPHANDLE lpW, USHORT us)
{
    return( CreatePipe(lpR, lpW, NULL, (DWORD) us) ? 0 : GetLastError());
}

HP_dosError(USHORT f)
{
    UINT ufError = 0;

    if (f == HARDERROR_ENABLE)
        ufError = SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX;

    SetErrorMode(ufError);
    return(0);
}

HP_dosLoadModule( LPCTSTR lpName, LPHANDLE ph)
{
    if (ph)
        *ph = LoadLibrary(lpName);
    else
        return(1);
    return(0);
}

HP_dosGetModHandle( LPCTSTR lpName, LPHANDLE ph)
{
    if (ph == NULL)
        return(-1);

    return( (*ph = GetModuleHandle(lpName)) ? 0 : GetLastError());
}

HWND HP_winWindowFromID( HWND hwnd, USHORT usID)
{
    int id = usID;

    switch (id)
        {
        case FID_HORZSCROLL: 
        case FID_VERTSCROLL: 
        case FID_TITLEBAR: 
        case FID_MINMAX:

           MessageBox(NULL, "Window Controls are not independent Windows",
                "OS/2 conversion Error", MB_ICONHAND | MB_OK);

            // FALL THRU
        case FID_CLIENT:
            return(hwnd);

        case FID_MENU:
            return((HWND) GetMenu(hwnd));

        case FID_SYSMENU:
            return((HWND) GetSystemMenu(hwnd, FALSE));

        default:
            return(GetDlgItem(hwnd, id));

        }
}


BOOL  HP_Entry (HANDLE hDLL, DWORD dwReason, LPVOID lpReserved)
{ 
  switch (dwReason)
  { 
  case DLL_PROCESS_ATTACH:
        InitializeCriticalSection(&HP_cs_mutex);
        HP_event_sem = CreateEvent(NULL, TRUE, FALSE, NULL);

      break;
  case DLL_THREAD_ATTACH:
      break;
  case DLL_THREAD_DETACH:
      break;
  case DLL_PROCESS_DETACH:
        DeleteCriticalSection(&HP_cs_mutex);
        CloseHandle(HP_event_sem);
      break;
  }
  return TRUE;
  UNREFERENCED_PARAMETER(hDLL);
  UNREFERENCED_PARAMETER(lpReserved);
}

