You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
711 lines
22 KiB
711 lines
22 KiB
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
|
|
#include <windows.h>
|
|
#include <winspool.h>
|
|
#include <winsplp.h>
|
|
|
|
#include <winbase.h>
|
|
#include "enumports.h"
|
|
#include "usbmon.h"
|
|
|
|
|
|
int iGMessageLevel;
|
|
PUSBMON_BASENAME GpBaseNameList;
|
|
HANDLE hMonitorSemaphore=NULL;
|
|
HANDLE hReadWriteSemaphore=NULL;
|
|
|
|
BOOL WINAPI USBMON_OpenPort(LPWSTR pName, PHANDLE pHandle);
|
|
BOOL WINAPI USBMON_StartDocPort(HANDLE hPort, LPWSTR pPrinterName, DWORD JobId, DWORD Level, LPBYTE pDocInfo);
|
|
BOOL WINAPI USBMON_WritePort(HANDLE hPort, LPBYTE pBuffer, DWORD cbBuf,LPDWORD pcbWritten);
|
|
BOOL WINAPI USBMON_ReadPort(HANDLE hPort, LPBYTE pBuffer, DWORD cbBuffer,LPDWORD pcbRead);
|
|
BOOL WINAPI USBMON_EndDocPort(HANDLE hPort);
|
|
BOOL WINAPI USBMON_ClosePort(HANDLE hPort);
|
|
BOOL WINAPI USBMON_SetPortTimeOuts(HANDLE hPort, LPCOMMTIMEOUTS lpCTO, DWORD reserved);
|
|
BOOL WINAPI USBMON_XcvOpenPort(LPCWSTR pszObject, ACCESS_MASK GrantedAccess, PHANDLE phXcv);
|
|
DWORD WINAPI USBMON_XcvDataPort(HANDLE hXcv,LPCWSTR pszDataName,PBYTE pInputData,DWORD cbInputData,PBYTE pOutputData,DWORD cbOutputData,PDWORD pcbOutputNeeded);
|
|
BOOL WINAPI USBMON_XcvClosePort(HANDLE hXcv);
|
|
BOOL USBMON_GetPrinterDataFromPort(HANDLE hPort,DWORD ControlID,LPWSTR pValueName,LPWSTR lpInBuffer,DWORD cbInBuffer,LPWSTR lpOutBuffer,DWORD cbOutBuffer,LPDWORD lpcbReturned);
|
|
void vLoadBaseNames(HKEY hPortsKey,PUSBMON_BASENAME *ppHead);
|
|
void vInterlockedClosePort(PUSBMON_PORT_INFO pPortInfo);
|
|
void vInterlockedOpenPort(PUSBMON_PORT_INFO pPortInfo);
|
|
void vInterlockedReOpenPort(PUSBMON_PORT_INFO pPortInfo);
|
|
LPMONITOREX WINAPI JobyInitializePrintMonitor(LPWSTR pRegistryRoot);
|
|
VOID CALLBACK ReadWriteCallback(DWORD dwErrorCode,DWORD dwNumberOfBytesTranfsered,LPOVERLAPPED lpOverlapped);
|
|
|
|
int iGetMessageLevel();
|
|
|
|
typedef struct OverlappedResults_def
|
|
{
|
|
DWORD dwErrorCode;
|
|
DWORD dwBytesTransfered;
|
|
} OverlappedResults,*pOverlappedResults;
|
|
|
|
|
|
|
|
BOOL APIENTRY DllMain(HANDLE hModule,
|
|
DWORD ul_reason_for_call,
|
|
LPVOID lpReserved)
|
|
{
|
|
|
|
return TRUE;
|
|
}; /*end function DllMain*/
|
|
|
|
|
|
|
|
|
|
int iGetMessageLevel()
|
|
{
|
|
HKEY hRegKey;
|
|
int iReturn=1; //default value is 1; "errors only"
|
|
DWORD dwValue,dwSize;
|
|
|
|
dwSize=sizeof(dwValue);
|
|
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Microsoft\\USBPRINT",0,KEY_QUERY_VALUE,&hRegKey)==ERROR_SUCCESS)
|
|
if(RegQueryValueEx(hRegKey,L"MonitorMessageLevel",0,NULL,(LPBYTE)&dwValue,&dwSize)==ERROR_SUCCESS)
|
|
iReturn=(int)dwValue;
|
|
return iReturn;
|
|
|
|
|
|
} /*end function iGetMessageLevel*/
|
|
|
|
|
|
LPMONITOREX WINAPI InitializePrintMonitor(LPWSTR pRegistryRoot)
|
|
{
|
|
LPMONITOREX lpMonitorInfo=NULL;
|
|
LONG lResult;
|
|
HKEY hRootKey,hPortsKey;
|
|
DWORD dwDisp;
|
|
|
|
|
|
iGMessageLevel=iGetMessageLevel();
|
|
OutputDebugStringD2("USBMON: Head of InitializePrintMonitor\n");
|
|
|
|
hMonitorSemaphore=CreateSemaphore(NULL,1,1,NULL);
|
|
if(hMonitorSemaphore==NULL)
|
|
{
|
|
OutputDebugStringD1("USBMON: Unable to initialize Monitor semaphore\n");
|
|
return FALSE;
|
|
}
|
|
|
|
hReadWriteSemaphore=CreateSemaphore(NULL,1,1,NULL);
|
|
if(hReadWriteSemaphore==NULL)
|
|
{
|
|
OutputDebugStringD1("USBMON: Unable to initialize ReadWrite semaphore\n");
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
OutputDebugStringD3("USBMON: Registry root: ");
|
|
OutputDebugStringWD3(pRegistryRoot);
|
|
OutputDebugStringD3("\n");
|
|
|
|
pPortInfoG=NULL;
|
|
// lResult=RegOpenKeyExW(HKEY_LOCAL_MACHINE,pRegistryRoot,0,KEY_ALL_ACCESS,&hRootKey);
|
|
lResult=RegCreateKeyExW(HKEY_LOCAL_MACHINE,pRegistryRoot,0,NULL,0,KEY_ALL_ACCESS,NULL,&hRootKey,&dwDisp);
|
|
if(lResult==ERROR_SUCCESS)
|
|
{
|
|
lResult=RegCreateKeyExW(hRootKey,L"PORTS",0,NULL,0,KEY_ALL_ACCESS,NULL,&hPortsKey,&dwDisp);
|
|
RegCloseKey(hRootKey);
|
|
}
|
|
if(lResult==ERROR_SUCCESS)
|
|
{
|
|
OutputDebugStringD3("USBMON: hPortsKeyG is good\n");
|
|
hPortsKeyG=hPortsKey;
|
|
GpBaseNameList=NULL;
|
|
vLoadBaseNames(hPortsKey,&GpBaseNameList);
|
|
lpMonitorInfo=(LPMONITOREX)GlobalAlloc(0,sizeof(MONITOREX));
|
|
if(lpMonitorInfo!=NULL)
|
|
{
|
|
lpMonitorInfo->dwMonitorSize=sizeof(MONITOR);
|
|
lpMonitorInfo->Monitor.pfnEnumPorts=USBMON_EnumPorts;
|
|
lpMonitorInfo->Monitor.pfnOpenPort=USBMON_OpenPort;
|
|
lpMonitorInfo->Monitor.pfnOpenPortEx=NULL; //Not required for port monitors
|
|
lpMonitorInfo->Monitor.pfnStartDocPort=USBMON_StartDocPort;
|
|
lpMonitorInfo->Monitor.pfnWritePort=USBMON_WritePort;
|
|
lpMonitorInfo->Monitor.pfnReadPort=USBMON_ReadPort;
|
|
lpMonitorInfo->Monitor.pfnEndDocPort=USBMON_EndDocPort;
|
|
lpMonitorInfo->Monitor.pfnClosePort=USBMON_ClosePort;
|
|
lpMonitorInfo->Monitor.pfnAddPort=NULL; //Obsolete
|
|
lpMonitorInfo->Monitor.pfnAddPortEx=NULL; //Obsolete
|
|
lpMonitorInfo->Monitor.pfnConfigurePort=NULL; //Obsolete
|
|
lpMonitorInfo->Monitor.pfnDeletePort=NULL; //Obsolete
|
|
lpMonitorInfo->Monitor.pfnGetPrinterDataFromPort=USBMON_GetPrinterDataFromPort;
|
|
lpMonitorInfo->Monitor.pfnSetPortTimeOuts=USBMON_SetPortTimeOuts;
|
|
// lpMonitorInfo->Monitor.pfnXcvOpenPort=USBMON_XcvOpenPort;
|
|
lpMonitorInfo->Monitor.pfnXcvOpenPort=NULL;
|
|
// lpMonitorInfo->Monitor.pfnXcvDataPort=USBMON_XcvDataPort;
|
|
lpMonitorInfo->Monitor.pfnXcvDataPort=NULL;
|
|
// lpMonitorInfo->Monitor.pfnXcvClosePort=USBMON_XcvClosePort;
|
|
lpMonitorInfo->Monitor.pfnXcvClosePort=NULL;
|
|
}
|
|
else
|
|
{
|
|
OutputDebugStringD1("USBMON: Error, Out of memory\n");
|
|
}
|
|
} /*end if reg keys OK*/
|
|
else
|
|
{
|
|
OutputDebugStringD1("USBMON: Error, Unable to get reg keys!\n");
|
|
}
|
|
|
|
GpBaseNameList=NULL;
|
|
return lpMonitorInfo;
|
|
};
|
|
|
|
|
|
|
|
BOOL USBMON_GetPrinterDataFromPort(
|
|
HANDLE hPort,
|
|
DWORD ControlID,
|
|
LPWSTR pValueName,
|
|
LPWSTR lpInBuffer,
|
|
DWORD cbInBuffer,
|
|
LPWSTR lpOutBuffer,
|
|
DWORD cbOutBuffer,
|
|
LPDWORD lpcbReturned)
|
|
{
|
|
|
|
BOOL bStatus;
|
|
PUSBMON_PORT_INFO pPortInfo;
|
|
HANDLE hPrinter;
|
|
|
|
|
|
if(ControlID==0)
|
|
{
|
|
OutputDebugStringD2("USBMON: GetPrinterDataFromPort Control ID==0, bailing. requested value==");
|
|
OutputDebugStringWD2(pValueName);
|
|
OutputDebugStringD2("\n");
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE; //need to set last error here.
|
|
}
|
|
|
|
|
|
pPortInfo=(PUSBMON_PORT_INFO)hPort;
|
|
hPrinter=pPortInfo->hPrinter;
|
|
|
|
OutputDebugStringD3("USBMON: Before DeviceIoControl\n");
|
|
bStatus=DeviceIoControl(hPrinter,ControlID,lpInBuffer,cbInBuffer,lpOutBuffer,cbOutBuffer,lpcbReturned,NULL);
|
|
if(!bStatus)
|
|
{
|
|
OutputDebugStringD2("USBMON: USBMON_GetPrinterDataFromPort failing\n");
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
}
|
|
else
|
|
{
|
|
OutputDebugStringD2("USBMON: USBMON_GetPrinterDataFromPort Success\n");
|
|
SetLastError(ERROR_SUCCESS);
|
|
}
|
|
return bStatus;
|
|
} /*end function USBMON_GetPrinterDataFromPort*/
|
|
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI USBMON_OpenPort(LPWSTR pName, PHANDLE pHandle)
|
|
{
|
|
PUSBMON_PORT_INFO pWalkPorts;
|
|
BOOL bFound=FALSE;
|
|
|
|
|
|
OutputDebugStringD2("USBMON: Head of USBMON_OpenPort\n");
|
|
pWalkPorts=pPortInfoG;
|
|
wsprintfW((WCHAR *)szDebugBuff,L"USBMON: OpenPort Looking for \"%s\"\n",pName);
|
|
OutputDebugStringWD2((WCHAR *)szDebugBuff);
|
|
while((bFound==FALSE)&&(pWalkPorts!=NULL))
|
|
{
|
|
wsprintfW((WCHAR *)szDebugBuff,L"USBMON: Looking at node \"%s\"\n",pWalkPorts->szPortName);
|
|
OutputDebugStringWD3((WCHAR *)szDebugBuff);
|
|
|
|
if(lstrcmp(pName,pWalkPorts->szPortName)==0)
|
|
bFound=TRUE;
|
|
else
|
|
pWalkPorts=pWalkPorts->pNext;
|
|
}
|
|
if(bFound)
|
|
{
|
|
|
|
wsprintfW((WCHAR *)szDebugBuff,L"USBMON: About to open path: \"%s\"\n",pWalkPorts->DevicePath);
|
|
OutputDebugStringD3(szDebugBuff);
|
|
|
|
// pWalkPorts->hDeviceHandle=CreateFile(pWalkPorts->DevicePath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
|
|
// if(pWalkPorts->hDeviceHandle!=INVALID_HANDLE_VALUE)
|
|
// {
|
|
*pHandle=(HANDLE)pWalkPorts;
|
|
pWalkPorts->ReadTimeoutMultiplier=0;
|
|
pWalkPorts-> ReadTimeoutConstant=60000;
|
|
pWalkPorts->WriteTimeoutMultiplier=0;
|
|
pWalkPorts->WriteTimeoutConstant=60000;
|
|
|
|
OutputDebugStringD3("USBMON: USBMON_OpenPort returning TRUE\n");
|
|
return TRUE;
|
|
// }
|
|
}
|
|
*pHandle=INVALID_HANDLE_VALUE;
|
|
wsprintfA(szDebugBuff,"USBMON: USBMON_OpenPort returning FALSE, error=%d\n",GetLastError());
|
|
OutputDebugStringD1(szDebugBuff);
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL WINAPI USBMON_StartDocPort(HANDLE hPort, LPWSTR pPrinterName, DWORD JobId, DWORD Level, LPBYTE pDocInfo)
|
|
{
|
|
BOOL bResult;
|
|
HANDLE hPrinter;
|
|
PUSBMON_PORT_INFO pPortInfo;
|
|
|
|
OutputDebugStringD2("USBMON: Head of StartDocPort\n");
|
|
pPortInfo=(PUSBMON_PORT_INFO)hPort;
|
|
bResult=OpenPrinterW(pPrinterName,&hPrinter,NULL);
|
|
if(bResult==FALSE)
|
|
{
|
|
OutputDebugStringD1("USBMON: OpenPrinter failed\n");
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
pPortInfo->hPrinter=hPrinter;
|
|
pPortInfo->dwCurrentJob=JobId;
|
|
// pWalkPorts->hDeviceHandle=CreateFile(pWalPorts->DevicePath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
|
|
wsprintfW((WCHAR *)szDebugBuff,L"USBMON:---------------------------------- About to open path: \"%s\"\n",pPortInfo->DevicePath);
|
|
OutputDebugStringD3(szDebugBuff);
|
|
|
|
// pPortInfo->hDeviceHandle=CreateFile(pPortInfo->DevicePath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
|
|
vInterlockedOpenPort(pPortInfo);
|
|
OutputDebugStringD3("USBMON: CreateFile in StartDocPort\n");
|
|
if(pPortInfo->hDeviceHandle==INVALID_HANDLE_VALUE)
|
|
{
|
|
OutputDebugStringD1("USBMON: CreateFile on printer device object failed\n");
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
} /*end else bResult OK*/
|
|
|
|
}
|
|
|
|
|
|
BOOL WINAPI USBMON_ReadPort(HANDLE hPort, LPBYTE pBuffer, DWORD cbBuf,LPDWORD pcbWritten)
|
|
{
|
|
|
|
DWORD dwBytesToRead;
|
|
PUSBMON_PORT_INFO pPortInfo;
|
|
DWORD dwTimeout;
|
|
OVERLAPPED rOverlappedInfo;
|
|
BOOL bTimeOut=FALSE,bSuccess=TRUE;
|
|
OverlappedResults Results;
|
|
|
|
OutputDebugStringD3("USBMON: Head of ReadPort\n");
|
|
pPortInfo=(PUSBMON_PORT_INFO)hPort;
|
|
|
|
dwBytesToRead=cbBuf;
|
|
|
|
vInterlockedOpenPort(pPortInfo);
|
|
if(pPortInfo->hDeviceHandle==INVALID_HANDLE_VALUE)
|
|
{
|
|
OutputDebugStringD1("USBMON: CreateFile on printer device object (inside ReadPort) failed\n");
|
|
return FALSE;
|
|
} /*end else CreateFile failed*/
|
|
|
|
dwTimeout=(pPortInfo->ReadTimeoutMultiplier)*dwBytesToRead;
|
|
dwTimeout+=pPortInfo->ReadTimeoutConstant;
|
|
memset(&rOverlappedInfo,0,sizeof(rOverlappedInfo));
|
|
rOverlappedInfo.hEvent=(HANDLE)&Results;
|
|
|
|
if(ReadFileEx(pPortInfo->hDeviceHandle,pBuffer,dwBytesToRead,&rOverlappedInfo,ReadWriteCallback)==FALSE)
|
|
{
|
|
bSuccess=FALSE;
|
|
}
|
|
else
|
|
{
|
|
wsprintfA(szDebugBuff,"USBMON: Sleep time=%d\n",dwTimeout);
|
|
OutputDebugStringD3(szDebugBuff);
|
|
|
|
if(SleepEx(dwTimeout,TRUE)==0)
|
|
{
|
|
OutputDebugStringD1("USBMON: SleepEx failed or timed out\n");
|
|
CancelIo(pPortInfo->hDeviceHandle);
|
|
bSuccess=FALSE;
|
|
SetLastError(ERROR_TIMEOUT);
|
|
}
|
|
else
|
|
{
|
|
if(Results.dwErrorCode==0)
|
|
{
|
|
|
|
wsprintfA(szDebugBuff,"USBMON: bytes read=%u\n",*pcbWritten);
|
|
OutputDebugStringD3(szDebugBuff);
|
|
SetLastError(ERROR_SUCCESS);
|
|
OutputDebugStringD3(szDebugBuff);
|
|
}
|
|
else
|
|
{
|
|
OutputDebugStringD1("USBMON: callback reported error\n");
|
|
SetLastError(Results.dwErrorCode);
|
|
bSuccess=FALSE;
|
|
|
|
} /*end else callback reported error*/
|
|
} /*end else did not time out*/
|
|
*pcbWritten=Results.dwBytesTransfered;
|
|
} /*end able to start read*/
|
|
|
|
if(!bSuccess)
|
|
{
|
|
OutputDebugStringD2("USBMON: Re-opening port\n");
|
|
vInterlockedReOpenPort(pPortInfo);
|
|
}
|
|
|
|
vInterlockedClosePort(pPortInfo);
|
|
return bSuccess;
|
|
} /*end function ReadPort*/
|
|
|
|
|
|
|
|
BOOL WINAPI USBMON_WritePort(HANDLE hPort, LPBYTE pBuffer, DWORD cbBuf,LPDWORD pcbWritten)
|
|
{
|
|
|
|
DWORD dwBytesToWrite;
|
|
PUSBMON_PORT_INFO pPortInfo;
|
|
DWORD dwTimeout;
|
|
OVERLAPPED rOverlappedInfo;
|
|
BOOL bTimeOut=FALSE,bSuccess=TRUE;
|
|
OverlappedResults Results;
|
|
|
|
OutputDebugStringD3("USBMON: Head of WritePort\n");
|
|
pPortInfo=(PUSBMON_PORT_INFO)hPort;
|
|
|
|
if(cbBuf>MAX_WRITE_CHUNK)
|
|
dwBytesToWrite=MAX_WRITE_CHUNK;
|
|
else
|
|
dwBytesToWrite=cbBuf;
|
|
|
|
// pPortInfo->hDeviceHandle=CreateFile(pPortInfo->DevicePath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
|
|
vInterlockedOpenPort(pPortInfo);
|
|
if(pPortInfo->hDeviceHandle==INVALID_HANDLE_VALUE)
|
|
{
|
|
OutputDebugStringD1("USBMON: CreateFile on printer device object (inside WritePort) failed\n");
|
|
return FALSE;
|
|
} /*end else CreateFile failed*/
|
|
|
|
dwTimeout=(pPortInfo->WriteTimeoutMultiplier)*dwBytesToWrite;
|
|
dwTimeout+=pPortInfo->WriteTimeoutConstant;
|
|
memset(&rOverlappedInfo,0,sizeof(rOverlappedInfo));
|
|
rOverlappedInfo.hEvent=(HANDLE)&Results;
|
|
|
|
//wsprintfA(szDebugBuff,"USBMON:/*dd About to WriteFileEx; pPortInfo->hDeviceHandle=%x, pBuffer=%x, dwBytesToWrite=%x\n",pPortInfo->hDeviceHandle,
|
|
// pBuffer,dwBytesToWrite);
|
|
//OutputDebugStringD1(szDebugBuff);
|
|
|
|
if(WriteFileEx(pPortInfo->hDeviceHandle,pBuffer,dwBytesToWrite,&rOverlappedInfo,ReadWriteCallback)==FALSE)
|
|
{
|
|
bSuccess=FALSE;
|
|
}
|
|
else
|
|
{
|
|
wsprintfA(szDebugBuff,"USBMON: Sleep time=%d\n",dwTimeout);
|
|
OutputDebugStringD2(szDebugBuff);
|
|
|
|
if(SleepEx(dwTimeout,TRUE)==0)
|
|
{
|
|
OutputDebugStringD2("USBMON: SleepEx failed or timed out\n");
|
|
CancelIo(pPortInfo->hDeviceHandle);
|
|
bSuccess=FALSE;
|
|
SetLastError(ERROR_TIMEOUT);
|
|
}
|
|
else
|
|
{
|
|
if(Results.dwErrorCode==0)
|
|
{
|
|
|
|
wsprintfA(szDebugBuff,"USBMON: bytes written=%u\n",*pcbWritten);
|
|
OutputDebugStringD3(szDebugBuff);
|
|
SetLastError(ERROR_SUCCESS);
|
|
OutputDebugStringD3(szDebugBuff);
|
|
}
|
|
else
|
|
{
|
|
OutputDebugStringD3("USBMON: callback reported error\n");
|
|
SetLastError(Results.dwErrorCode);
|
|
bSuccess=FALSE;
|
|
|
|
} /*end else callback reported error*/
|
|
} /*end else did not time out*/
|
|
*pcbWritten=Results.dwBytesTransfered;
|
|
} /*end able to start write*/
|
|
|
|
if(!bSuccess)
|
|
{
|
|
OutputDebugStringD2("USBMON: Re-opening port\n");
|
|
vInterlockedReOpenPort(pPortInfo);
|
|
}
|
|
|
|
vInterlockedClosePort(pPortInfo);
|
|
return bSuccess;
|
|
} /*end function WritePort*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VOID CALLBACK ReadWriteCallback(DWORD dwErrorCode,DWORD dwNumberOfBytesTransfered,LPOVERLAPPED lpOverlapped)
|
|
{
|
|
pOverlappedResults pResults;
|
|
OutputDebugStringD2(" USBMON: ReadWriteCallback\n");
|
|
pResults=(pOverlappedResults)(lpOverlapped->hEvent);
|
|
pResults->dwErrorCode=dwErrorCode;
|
|
pResults->dwBytesTransfered=dwNumberOfBytesTransfered;
|
|
} /*end function ReadWriteCallback*/
|
|
|
|
|
|
BOOL WINAPI USBMON_EndDocPort(HANDLE hPort)
|
|
{
|
|
PUSBMON_PORT_INFO pPortInfo;
|
|
|
|
OutputDebugStringD3("USBMON: Head of EndDocPort\n");
|
|
|
|
pPortInfo=(PUSBMON_PORT_INFO)hPort;
|
|
|
|
SetJob(pPortInfo->hPrinter,pPortInfo->dwCurrentJob,0,NULL,JOB_CONTROL_SENT_TO_PRINTER);
|
|
ClosePrinter(pPortInfo->hPrinter);
|
|
|
|
vInterlockedClosePort(pPortInfo);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL WINAPI USBMON_ClosePort(HANDLE hPort)
|
|
{
|
|
OutputDebugStringD3("USBMON: Head of ClosePort\n");
|
|
// CloseHandle( ((PUSBMON_PORT_INFO)hPort)->hDeviceHandle);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI USBMON_SetPortTimeOuts(HANDLE hPort, LPCOMMTIMEOUTS lpCTO, DWORD reserved)
|
|
{
|
|
PUSBMON_PORT_INFO pPortInfo;
|
|
|
|
OutputDebugStringD3(" USBMON: Head of SetPortTimeOuts\n");
|
|
|
|
pPortInfo=(PUSBMON_PORT_INFO)hPort;
|
|
wsprintfA(szDebugBuff,"USBMON: SetPortTimeOut, ReadMultiplier=%u, ReadConstant=%u\n",
|
|
lpCTO->ReadTotalTimeoutMultiplier,lpCTO->ReadTotalTimeoutConstant);
|
|
OutputDebugStringD2(szDebugBuff);
|
|
pPortInfo->ReadTimeoutMultiplier=lpCTO->ReadTotalTimeoutMultiplier;
|
|
pPortInfo->ReadTimeoutConstant=lpCTO->ReadTotalTimeoutConstant;
|
|
pPortInfo->WriteTimeoutMultiplier=lpCTO->WriteTotalTimeoutMultiplier;
|
|
pPortInfo->WriteTimeoutConstant=lpCTO->WriteTotalTimeoutConstant;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI USBMON_XcvOpenPort(LPCWSTR pszObject, ACCESS_MASK GrantedAccess, PHANDLE phXcv)
|
|
{
|
|
OutputDebugStringD2("USBMON: Head of XcvOpenPort\n");
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD WINAPI USBMON_XcvDataPort(HANDLE hXcv,
|
|
LPCWSTR pszDataName,
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded)
|
|
{
|
|
OutputDebugStringD2("USBMON: Head of XcvDataPort\n");
|
|
|
|
return ERROR_INVALID_FUNCTION;
|
|
}
|
|
|
|
BOOL WINAPI USBMON_XcvClosePort(HANDLE hXcv)
|
|
{
|
|
OutputDebugStringD2("USBMON: Head of XcvClosePort\n");
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
AtoI - Convert a string to a signed or unsigned integer
|
|
|
|
IN pStr = ASCIZ representation of number with optional leading/trailing
|
|
whitespace and optional leading '-'.
|
|
Radix = Radix to use for conversion (2, 8, 10, or 16)
|
|
OUT *pResult = Numeric result, or unchanged on failure
|
|
Returns 1 on success, 0 if malformed string.
|
|
|
|
Note Not reentrant
|
|
|
|
*/
|
|
UINT AtoI(PUCHAR pStr, UINT Radix, PUINT pResult)
|
|
{
|
|
UINT r = 0;
|
|
UINT Sign = 0;
|
|
UCHAR c;
|
|
UINT d;
|
|
|
|
while (*pStr == ' ' || *pStr == '\t')
|
|
pStr++;
|
|
|
|
if (*pStr == '-') {
|
|
Sign = 1;
|
|
pStr++;
|
|
}
|
|
|
|
if (*pStr == 0)
|
|
return 0; // Empty string!
|
|
|
|
while ((c = *pStr) != 0 && c != ' ' && c != '\t') {
|
|
if (c >= '0' && c <= '9')
|
|
d = c - '0';
|
|
else if (c >= 'A' && c <= 'F')
|
|
d = c - ('A' - 10);
|
|
else if (c >= 'a' && c <= 'f')
|
|
d = c - ('a' - 10);
|
|
else
|
|
return 0; // Not a digit
|
|
if (d >= Radix)
|
|
return 0; // Not in radix
|
|
r = r*Radix+d;
|
|
pStr++;
|
|
}
|
|
|
|
while (*pStr == ' ' || *pStr == '\t')
|
|
pStr++;
|
|
|
|
if (*pStr != 0)
|
|
return 0; // Garbage at end of string
|
|
|
|
if (Sign)
|
|
r = (UINT)(-(INT)r);
|
|
*pResult = r;
|
|
|
|
return 1; // Success!
|
|
}
|
|
|
|
void vLoadBaseNames(HKEY hRegKey, PUSBMON_BASENAME *ppHead)
|
|
{
|
|
PUSBMON_BASENAME pNew,pWalk;
|
|
WCHAR wcName[MAX_PORT_LEN];
|
|
int iIndex=0;
|
|
LONG lStatus;
|
|
LONG lDataSize;
|
|
int iCompare;
|
|
|
|
*ppHead=GlobalAlloc(0,sizeof(USBMON_PORT_INFO));
|
|
if(*ppHead==NULL)
|
|
return;
|
|
(*ppHead)->pNext=NULL;
|
|
wcscpy((*ppHead)->wcBaseName,L"USB");
|
|
|
|
lDataSize=MAX_PORT_LEN;
|
|
lStatus=RegEnumValue(hRegKey,iIndex++,wcName,&lDataSize,NULL,NULL,NULL,NULL);
|
|
while(lStatus==ERROR_SUCCESS)
|
|
{
|
|
pNew=GlobalAlloc(0,sizeof(USBMON_PORT_INFO));
|
|
if(pNew==NULL)
|
|
return;
|
|
wcscpy(pNew->wcBaseName,wcName);
|
|
if(wcscmp(pNew->wcBaseName,(*ppHead)->wcBaseName)<0)
|
|
{
|
|
pNew->pNext=*ppHead;
|
|
*ppHead=pNew;
|
|
} /*end if new first node*/
|
|
else
|
|
{
|
|
pWalk=*ppHead;
|
|
iCompare=-1;
|
|
while((iCompare<0)&&(pWalk->pNext!=NULL))
|
|
{
|
|
iCompare=wcscmp(pNew->wcBaseName,pWalk->pNext->wcBaseName);
|
|
if(iCompare<0)
|
|
pWalk=pWalk->pNext;
|
|
} /*end while walk*/
|
|
if(iCompare>0)
|
|
{
|
|
pNew->pNext=pWalk->pNext;
|
|
pWalk->pNext=pNew;
|
|
}
|
|
else if(iCompare==0)
|
|
{
|
|
GlobalFree(pNew);
|
|
} /*end if collision*/
|
|
} /*else not new first node*/
|
|
lDataSize=MAX_PORT_LEN;
|
|
lStatus=lStatus=RegEnumValue(hRegKey,iIndex++,wcName,&lDataSize,NULL,NULL,NULL,NULL);
|
|
} //end while more reg items
|
|
} //end function vLoadBaseNames
|
|
|
|
|
|
|
|
|
|
|
|
void vInterlockedOpenPort(PUSBMON_PORT_INFO pPortInfo)
|
|
{
|
|
OutputDebugStringD2("USBMON: Head of vInterlockedOpenPort\n");
|
|
|
|
WaitForSingleObjectEx(hReadWriteSemaphore,INFINITE,FALSE);
|
|
if((pPortInfo->iRefCount==0)||(pPortInfo->hDeviceHandle==INVALID_HANDLE_VALUE))
|
|
{
|
|
OutputDebugStringD3("USBMON: vInterlockedOpenPort, Really opening:");
|
|
OutputDebugStringWD3(pPortInfo->DevicePath);
|
|
OutputDebugStringD3("\n");
|
|
pPortInfo->hDeviceHandle=CreateFile(pPortInfo->DevicePath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
|
|
if(pPortInfo->hDeviceHandle!=INVALID_HANDLE_VALUE)
|
|
(pPortInfo->iRefCount)++;
|
|
}
|
|
else
|
|
{
|
|
OutputDebugStringD3("USBMON: vInterlockedOpenPort, Just incrementing ref count\n");
|
|
(pPortInfo->iRefCount)++;
|
|
}
|
|
wsprintfA(szDebugBuff,"USBMON: vInterlockedOpenPort, iRefCount=%d\n",pPortInfo->iRefCount);
|
|
OutputDebugStringD2(szDebugBuff);
|
|
ReleaseSemaphore(hReadWriteSemaphore,1,NULL);
|
|
|
|
} /*end function vInterlockedOpenPort*/
|
|
|
|
|
|
|
|
|
|
void vInterlockedClosePort(PUSBMON_PORT_INFO pPortInfo)
|
|
{
|
|
OutputDebugStringD2("USBMON: Head of vInterlockedClosePort\n");
|
|
|
|
WaitForSingleObjectEx(hReadWriteSemaphore,INFINITE,FALSE);
|
|
(pPortInfo->iRefCount)--;
|
|
if(pPortInfo<0) {
|
|
DebugBreak();
|
|
pPortInfo=0;
|
|
}
|
|
if(pPortInfo->iRefCount==0)
|
|
{
|
|
CloseHandle(pPortInfo->hDeviceHandle);
|
|
pPortInfo->hDeviceHandle=INVALID_HANDLE_VALUE;
|
|
}
|
|
wsprintfA(szDebugBuff,"USBMON: vInterlockedClosePort, iRefCount=%d\n",pPortInfo->iRefCount);
|
|
OutputDebugStringD2(szDebugBuff);
|
|
ReleaseSemaphore(hReadWriteSemaphore,1,NULL);
|
|
} /*end function vInterlockedClosePort*/
|
|
|
|
|
|
void vInterlockedReOpenPort(PUSBMON_PORT_INFO pPortInfo)
|
|
{
|
|
OutputDebugStringD2("USBMON: Head of vInterlockedReOpenPort\n");
|
|
WaitForSingleObjectEx(hReadWriteSemaphore,INFINITE,FALSE);
|
|
//
|
|
// big problem. what if another thread is using the handle
|
|
//
|
|
CloseHandle(pPortInfo->hDeviceHandle);
|
|
OutputDebugStringD3("USBMON: vInterlockedReOpenPort, Really opening----------------------------------------------:\n");
|
|
OutputDebugStringWD3(pPortInfo->DevicePath);
|
|
OutputDebugStringD3("\n");
|
|
pPortInfo->hDeviceHandle=CreateFile(pPortInfo->DevicePath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
|
|
if(pPortInfo->hDeviceHandle==INVALID_HANDLE_VALUE)
|
|
// --pPortInfo->iRefCount;
|
|
wsprintfA(szDebugBuff,"USBMON: vInterlockedReOpenPort, iRefcCount=%d\n",pPortInfo->iRefCount);
|
|
OutputDebugStringD2(szDebugBuff);
|
|
ReleaseSemaphore(hReadWriteSemaphore,1,NULL);
|
|
} /*end function vInterlockedReOpenPort*/
|