/* $Id: hmdevio.cpp,v 1.29 2002-12-20 10:38:56 sandervl Exp $ */ /* * Win32 Device IOCTL API functions for OS/2 * * Copyright 1998 Sander van Leeuwen * * * Project Odin Software License can be found in LICENSE.TXT * */ #define INCL_DOSPROFILE #define INCL_DOSDEVICES #define INCL_DOSDEVIOCTL #define INCL_GPI #define INCL_DOSFILEMGR /* File Manager values */ #define INCL_DOSERRORS /* DOS Error values */ #define INCL_DOSPROCESS /* DOS Process values */ #define INCL_DOSMISC /* DOS Miscellanous values */ #include //Odin32 OS/2 api wrappers #include #include #include #include #include #include #include "hmdevio.h" #include "exceptutil.h" #include "oslibdos.h" #define DBG_LOCALLOG DBG_hmdevio #include "dbglocal.h" static WIN32DRV knownDriver[] = { {0} }; static int nrKnownDrivers = 0; // = sizeof(knownDriver)/sizeof(WIN32DRV); //****************************************************************************** //****************************************************************************** void RegisterDevices() { HMDeviceDriver *driver; DWORD rc; for(int i=0;i "drvname$" } } rc = 0; } } RegCloseKey(hkDrivers); } return; } //****************************************************************************** //****************************************************************************** BOOL WIN32API RegisterCustomDriver(PFNDRVOPEN pfnDriverOpen, PFNDRVCLOSE pfnDriverClose, PFNDRVIOCTL pfnDriverIOCtl, PFNDRVREAD pfnDriverRead, PFNDRVWRITE pfnDriverWrite, PFNDRVCANCELIO pfnDriverCancelIo, PFNDRVGETOVERLAPPEDRESULT pfnDriverGetOverlappedResult, LPCSTR lpDeviceName, LPVOID lpDriverData) { HMCustomDriver *driver; DWORD rc; dprintf(("RegisterCustomDriver %s", lpDeviceName)); driver = new HMCustomDriver(pfnDriverOpen, pfnDriverClose, pfnDriverIOCtl, pfnDriverRead, pfnDriverWrite, pfnDriverCancelIo, pfnDriverGetOverlappedResult, lpDeviceName, lpDriverData); if(driver == NULL) { DebugInt3(); return FALSE; } rc = HMDeviceRegister((LPSTR)lpDeviceName, driver); if (rc != NO_ERROR) { /* check for errors */ dprintf(("KERNEL32:RegisterDevices: registering %s failed with %u.\n", lpDeviceName, rc)); return FALSE; } return TRUE; } //****************************************************************************** //****************************************************************************** HMDeviceDriver::HMDeviceDriver(LPCSTR lpDeviceName, LPSTR lpOS2DevName, BOOL fCreate, WINIOCTL pDevIOCtl) : HMDeviceHandler(lpDeviceName) { this->fCreateFile = fCreateFile; this->szOS2Name = lpOS2DevName; this->devIOCtl = pDevIOCtl; } //****************************************************************************** //****************************************************************************** HMDeviceDriver::HMDeviceDriver(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName) { } //****************************************************************************** //****************************************************************************** DWORD HMDeviceDriver::CreateFile (LPCSTR lpFileName, PHMHANDLEDATA pHMHandleData, PVOID lpSecurityAttributes, PHMHANDLEDATA pHMHandleDataTemplate) { APIRET rc; HFILE hfFileHandle = 0L; /* Handle for file being manipulated */ ULONG ulAction = 0; /* Action taken by DosOpen */ ULONG sharetype = 0; if(pHMHandleData->dwAccess & (GENERIC_READ | GENERIC_WRITE)) sharetype |= OPEN_ACCESS_READWRITE; else if(pHMHandleData->dwAccess & GENERIC_WRITE) sharetype |= OPEN_ACCESS_WRITEONLY; if(pHMHandleData->dwShare == 0) sharetype |= OPEN_SHARE_DENYREADWRITE; else if(pHMHandleData->dwShare & (FILE_SHARE_READ | FILE_SHARE_WRITE)) sharetype |= OPEN_SHARE_DENYNONE; else if(pHMHandleData->dwShare & FILE_SHARE_WRITE) sharetype |= OPEN_SHARE_DENYREAD; else if(pHMHandleData->dwShare & FILE_SHARE_READ) sharetype |= OPEN_SHARE_DENYWRITE; if(szOS2Name[0] == 0) { pHMHandleData->hHMHandle = 0; return (NO_ERROR); } tryopen: rc = DosOpen( szOS2Name, /* File path name */ &hfFileHandle, /* File handle */ &ulAction, /* Action taken */ 0, FILE_NORMAL, FILE_OPEN, sharetype, 0L); /* No extended attribute */ if(rc == ERROR_TOO_MANY_OPEN_FILES) { ULONG CurMaxFH; LONG ReqCount = 32; rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH); if(rc) { dprintf(("DosSetRelMaxFH returned %d", rc)); return error2WinError(rc); } dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH)); goto tryopen; } dprintf(("DosOpen %s returned %d\n", szOS2Name, rc)); if(rc == NO_ERROR) { pHMHandleData->hHMHandle = hfFileHandle; return (NO_ERROR); } else return(error2WinError(rc)); } //****************************************************************************** //****************************************************************************** BOOL HMDeviceDriver::CloseHandle(PHMHANDLEDATA pHMHandleData) { DWORD rc = 0; if(pHMHandleData->hHMHandle) { rc = DosClose(pHMHandleData->hHMHandle); } pHMHandleData->hHMHandle = 0; return rc; } //****************************************************************************** //****************************************************************************** BOOL HMDeviceDriver::DeviceIoControl(PHMHANDLEDATA pHMHandleData, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { return devIOCtl(pHMHandleData->hHMHandle, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped); } //****************************************************************************** //****************************************************************************** HMCustomDriver::HMCustomDriver(HINSTANCE hInstance, LPCSTR lpDeviceName, LPVOID lpDriverData) : HMDeviceDriver(lpDeviceName), hDrvDll(0), lpDriverData(NULL) { hDrvDll = hInstance ; pfnDriverOpen = (PFNDRVOPEN) GetProcAddress(hDrvDll, "DrvOpen"); pfnDriverClose = (PFNDRVCLOSE)GetProcAddress(hDrvDll, "DrvClose"); pfnDriverRead = (PFNDRVREAD) GetProcAddress(hDrvDll, "DrvRead"); pfnDriverWrite = (PFNDRVWRITE)GetProcAddress(hDrvDll, "DrvWrite"); pfnDriverIOCtl = (PFNDRVIOCTL)GetProcAddress(hDrvDll, "DrvIOCtl"); } //****************************************************************************** //****************************************************************************** HMCustomDriver::HMCustomDriver(PFNDRVOPEN pfnDriverOpen, PFNDRVCLOSE pfnDriverClose, PFNDRVIOCTL pfnDriverIOCtl, PFNDRVREAD pfnDriverRead, PFNDRVWRITE pfnDriverWrite, PFNDRVCANCELIO pfnDriverCancelIo, PFNDRVGETOVERLAPPEDRESULT pfnDriverGetOverlappedResult, LPCSTR lpDeviceName, LPVOID lpDriverData) : HMDeviceDriver(lpDeviceName), hDrvDll(0) { if(!pfnDriverOpen || !pfnDriverClose) { DebugInt3(); } this->pfnDriverOpen = pfnDriverOpen; this->pfnDriverClose = pfnDriverClose; this->pfnDriverIOCtl = pfnDriverIOCtl; this->pfnDriverRead = pfnDriverRead; this->pfnDriverWrite = pfnDriverWrite; this->pfnDriverCancelIo = pfnDriverCancelIo; this->pfnDriverGetOverlappedResult = pfnDriverGetOverlappedResult; this->lpDriverData = lpDriverData; } //****************************************************************************** //****************************************************************************** HMCustomDriver::~HMCustomDriver() { if(hDrvDll) FreeLibrary(hDrvDll); } //****************************************************************************** //****************************************************************************** DWORD HMCustomDriver::CreateFile (LPCSTR lpFileName, PHMHANDLEDATA pHMHandleData, PVOID lpSecurityAttributes, PHMHANDLEDATA pHMHandleDataTemplate) { pHMHandleData->hHMHandle = pfnDriverOpen(lpDriverData, pHMHandleData->dwAccess, pHMHandleData->dwShare, pHMHandleData->dwFlags, (PVOID *)&pHMHandleData->dwUserData); if(pHMHandleData->hHMHandle == INVALID_HANDLE_VALUE_W) { return GetLastError(); } return ERROR_SUCCESS_W; } //****************************************************************************** //****************************************************************************** BOOL HMCustomDriver::CloseHandle(PHMHANDLEDATA pHMHandleData) { if(pHMHandleData->hHMHandle) { pfnDriverClose(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, (LPVOID)pHMHandleData->dwUserData); } pHMHandleData->hHMHandle = 0; return TRUE; } //****************************************************************************** //****************************************************************************** BOOL HMCustomDriver::DeviceIoControl(PHMHANDLEDATA pHMHandleData, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { BOOL ret; if(pfnDriverIOCtl == NULL) { dprintf(("HMCustomDriver::DeviceIoControl: pfnDriverIOCtl == NULL")); ::SetLastError(ERROR_INVALID_FUNCTION_W); return FALSE; } ret = pfnDriverIOCtl(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped, (LPVOID)pHMHandleData->dwUserData); dprintf(("DeviceIoControl %x returned %d", dwIoControlCode, ret)); return ret; } /***************************************************************************** * Name : BOOL HMCustomDriver::ReadFile * Purpose : read data from handle / device * Parameters: PHMHANDLEDATA pHMHandleData, * LPCVOID lpBuffer, * DWORD nNumberOfBytesToRead, * LPDWORD lpNumberOfBytesRead, * LPOVERLAPPED lpOverlapped * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine * Variables : * Result : Boolean * Remark : * Status : * * Author : SvL *****************************************************************************/ BOOL HMCustomDriver::ReadFile(PHMHANDLEDATA pHMHandleData, LPCVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { BOOL ret; if(pfnDriverRead == NULL) { dprintf(("HMCustomDriver::ReadFile: pfnDriverRead == NULL")); ::SetLastError(ERROR_INVALID_FUNCTION_W); return FALSE; } ret = pfnDriverRead(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine, (LPVOID)pHMHandleData->dwUserData); dprintf(("pfnDriverRead %x %x %x %x %x %x returned %x", pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine, ret)); return ret; } /***************************************************************************** * Name : BOOL HMCustomDriver::WriteFile * Purpose : write data to handle / device * Parameters: PHMHANDLEDATA pHMHandleData, * LPCVOID lpBuffer, * DWORD nNumberOfBytesToWrite, * LPDWORD lpNumberOfBytesWritten, * LPOVERLAPPED lpOverlapped * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine * Variables : * Result : Boolean * Remark : * Status : * * Author : SvL *****************************************************************************/ BOOL HMCustomDriver::WriteFile(PHMHANDLEDATA pHMHandleData, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { BOOL ret; if(pfnDriverWrite == NULL) { dprintf(("HMCustomDriver::WriteFile: pfnDriverWrite == NULL")); ::SetLastError(ERROR_INVALID_FUNCTION_W); return FALSE; } ret = pfnDriverWrite(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine, (LPVOID)pHMHandleData->dwUserData); dprintf(("pfnDriverWrite %x %x %x %x %x %x returned %x", pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine, ret)); return ret; } /***************************************************************************** * Name : DWORD HMCustomDriver::CancelIo * Purpose : cancel pending IO operation * Variables : * Result : * Remark : * Status : * * Author : SvL *****************************************************************************/ BOOL HMCustomDriver::CancelIo(PHMHANDLEDATA pHMHandleData) { BOOL ret; if(pfnDriverCancelIo == NULL) { dprintf(("HMCustomDriver::CancelIo: pfnDriverCancelIo == NULL")); ::SetLastError(ERROR_INVALID_FUNCTION_W); return FALSE; } ret = pfnDriverCancelIo(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, (LPVOID)pHMHandleData->dwUserData); dprintf(("pfnDriverCancelIo %x returned %x", pHMHandleData->hHMHandle, ret)); return ret; } /***************************************************************************** * Name : DWORD HMCustomDriver::GetOverlappedResult * Purpose : asynchronus I/O * Parameters: PHMHANDLEDATA pHMHandleData * LPOVERLAPPED arg2 * LPDWORD arg3 * BOOL arg4 * Variables : * Result : API returncode * Remark : * Status : * * Author : SvL *****************************************************************************/ BOOL HMCustomDriver::GetOverlappedResult(PHMHANDLEDATA pHMHandleData, LPOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait) { dprintf(("KERNEL32-HMCustomDriver: HMCustomDriver::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh)", pHMHandleData->hHMHandle, lpOverlapped, lpcbTransfer, fWait)); if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED_W)) { dprintf(("!WARNING!: GetOverlappedResult called for a handle that wasn't opened with FILE_FLAG_OVERLAPPED")); return TRUE; //NT4, SP6 doesn't fail } if(!lpOverlapped) { ::SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if(pfnDriverGetOverlappedResult == NULL) { dprintf(("HMCustomDriver::GetOverlappedResult: pfnDriverGetOverlappedResult == NULL")); ::SetLastError(ERROR_INVALID_FUNCTION_W); return FALSE; } return pfnDriverGetOverlappedResult(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, lpOverlapped, lpcbTransfer, fWait, (LPVOID)pHMHandleData->dwUserData); } extern "C" { //****************************************************************************** //****************************************************************************** BOOL WIN32API QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) { QWORD time; APIRET rc; #if 0 return FALSE; #else rc = DosTmrQueryTime(&time); if(rc) { dprintf(("DosTmrQueryTime returned %d\n", rc)); return(FALSE); } lpPerformanceCount->u.LowPart = time.ulLo; lpPerformanceCount->u.HighPart = time.ulHi; dprintf2(("QueryPerformanceCounter returned 0x%X%X\n", lpPerformanceCount->u.HighPart, lpPerformanceCount->u.LowPart)); return(TRUE); #endif } //****************************************************************************** //****************************************************************************** BOOL WIN32API QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency) { APIRET rc; ULONG freq; #if 0 return FALSE; #else rc = DosTmrQueryFreq(&freq); if(rc) { dprintf(("DosTmrQueryFreq returned %d\n", rc)); return(FALSE); } lpFrequency->u.LowPart = freq; lpFrequency->u.HighPart = 0; dprintf2(("QueryPerformanceFrequency returned 0x%X%X\n", lpFrequency->u.HighPart, lpFrequency->u.LowPart)); return(TRUE); #endif } //****************************************************************************** //****************************************************************************** } // extern "C"