Leaked source code of windows server 2003
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

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <winspool.h>
  6. #include <winsplp.h>
  7. #include <winbase.h>
  8. #include "enumports.h"
  9. #include "usbmon.h"
  10. int iGMessageLevel;
  11. PUSBMON_BASENAME GpBaseNameList;
  12. HANDLE hMonitorSemaphore=NULL;
  13. HANDLE hReadWriteSemaphore=NULL;
  14. BOOL WINAPI USBMON_OpenPort(LPWSTR pName, PHANDLE pHandle);
  15. BOOL WINAPI USBMON_StartDocPort(HANDLE hPort, LPWSTR pPrinterName, DWORD JobId, DWORD Level, LPBYTE pDocInfo);
  16. BOOL WINAPI USBMON_WritePort(HANDLE hPort, LPBYTE pBuffer, DWORD cbBuf,LPDWORD pcbWritten);
  17. BOOL WINAPI USBMON_ReadPort(HANDLE hPort, LPBYTE pBuffer, DWORD cbBuffer,LPDWORD pcbRead);
  18. BOOL WINAPI USBMON_EndDocPort(HANDLE hPort);
  19. BOOL WINAPI USBMON_ClosePort(HANDLE hPort);
  20. BOOL WINAPI USBMON_SetPortTimeOuts(HANDLE hPort, LPCOMMTIMEOUTS lpCTO, DWORD reserved);
  21. BOOL WINAPI USBMON_XcvOpenPort(LPCWSTR pszObject, ACCESS_MASK GrantedAccess, PHANDLE phXcv);
  22. DWORD WINAPI USBMON_XcvDataPort(HANDLE hXcv,LPCWSTR pszDataName,PBYTE pInputData,DWORD cbInputData,PBYTE pOutputData,DWORD cbOutputData,PDWORD pcbOutputNeeded);
  23. BOOL WINAPI USBMON_XcvClosePort(HANDLE hXcv);
  24. BOOL USBMON_GetPrinterDataFromPort(HANDLE hPort,DWORD ControlID,LPWSTR pValueName,LPWSTR lpInBuffer,DWORD cbInBuffer,LPWSTR lpOutBuffer,DWORD cbOutBuffer,LPDWORD lpcbReturned);
  25. void vLoadBaseNames(HKEY hPortsKey,PUSBMON_BASENAME *ppHead);
  26. void vInterlockedClosePort(PUSBMON_PORT_INFO pPortInfo);
  27. void vInterlockedOpenPort(PUSBMON_PORT_INFO pPortInfo);
  28. void vInterlockedReOpenPort(PUSBMON_PORT_INFO pPortInfo);
  29. LPMONITOREX WINAPI JobyInitializePrintMonitor(LPWSTR pRegistryRoot);
  30. VOID CALLBACK ReadWriteCallback(DWORD dwErrorCode,DWORD dwNumberOfBytesTranfsered,LPOVERLAPPED lpOverlapped);
  31. int iGetMessageLevel();
  32. typedef struct OverlappedResults_def
  33. {
  34. DWORD dwErrorCode;
  35. DWORD dwBytesTransfered;
  36. } OverlappedResults,*pOverlappedResults;
  37. BOOL APIENTRY DllMain(HANDLE hModule,
  38. DWORD ul_reason_for_call,
  39. LPVOID lpReserved)
  40. {
  41. return TRUE;
  42. }; /*end function DllMain*/
  43. int iGetMessageLevel()
  44. {
  45. HKEY hRegKey;
  46. int iReturn=1; //default value is 1; "errors only"
  47. DWORD dwValue,dwSize;
  48. dwSize=sizeof(dwValue);
  49. if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Microsoft\\USBPRINT",0,KEY_QUERY_VALUE,&hRegKey)==ERROR_SUCCESS)
  50. if(RegQueryValueEx(hRegKey,L"MonitorMessageLevel",0,NULL,(LPBYTE)&dwValue,&dwSize)==ERROR_SUCCESS)
  51. iReturn=(int)dwValue;
  52. return iReturn;
  53. } /*end function iGetMessageLevel*/
  54. LPMONITOREX WINAPI InitializePrintMonitor(LPWSTR pRegistryRoot)
  55. {
  56. LPMONITOREX lpMonitorInfo=NULL;
  57. LONG lResult;
  58. HKEY hRootKey,hPortsKey;
  59. DWORD dwDisp;
  60. iGMessageLevel=iGetMessageLevel();
  61. OutputDebugStringD2("USBMON: Head of InitializePrintMonitor\n");
  62. hMonitorSemaphore=CreateSemaphore(NULL,1,1,NULL);
  63. if(hMonitorSemaphore==NULL)
  64. {
  65. OutputDebugStringD1("USBMON: Unable to initialize Monitor semaphore\n");
  66. return FALSE;
  67. }
  68. hReadWriteSemaphore=CreateSemaphore(NULL,1,1,NULL);
  69. if(hReadWriteSemaphore==NULL)
  70. {
  71. OutputDebugStringD1("USBMON: Unable to initialize ReadWrite semaphore\n");
  72. return FALSE;
  73. }
  74. OutputDebugStringD3("USBMON: Registry root: ");
  75. OutputDebugStringWD3(pRegistryRoot);
  76. OutputDebugStringD3("\n");
  77. pPortInfoG=NULL;
  78. // lResult=RegOpenKeyExW(HKEY_LOCAL_MACHINE,pRegistryRoot,0,KEY_ALL_ACCESS,&hRootKey);
  79. lResult=RegCreateKeyExW(HKEY_LOCAL_MACHINE,pRegistryRoot,0,NULL,0,KEY_ALL_ACCESS,NULL,&hRootKey,&dwDisp);
  80. if(lResult==ERROR_SUCCESS)
  81. {
  82. lResult=RegCreateKeyExW(hRootKey,L"PORTS",0,NULL,0,KEY_ALL_ACCESS,NULL,&hPortsKey,&dwDisp);
  83. RegCloseKey(hRootKey);
  84. }
  85. if(lResult==ERROR_SUCCESS)
  86. {
  87. OutputDebugStringD3("USBMON: hPortsKeyG is good\n");
  88. hPortsKeyG=hPortsKey;
  89. GpBaseNameList=NULL;
  90. vLoadBaseNames(hPortsKey,&GpBaseNameList);
  91. lpMonitorInfo=(LPMONITOREX)GlobalAlloc(0,sizeof(MONITOREX));
  92. if(lpMonitorInfo!=NULL)
  93. {
  94. lpMonitorInfo->dwMonitorSize=sizeof(MONITOR);
  95. lpMonitorInfo->Monitor.pfnEnumPorts=USBMON_EnumPorts;
  96. lpMonitorInfo->Monitor.pfnOpenPort=USBMON_OpenPort;
  97. lpMonitorInfo->Monitor.pfnOpenPortEx=NULL; //Not required for port monitors
  98. lpMonitorInfo->Monitor.pfnStartDocPort=USBMON_StartDocPort;
  99. lpMonitorInfo->Monitor.pfnWritePort=USBMON_WritePort;
  100. lpMonitorInfo->Monitor.pfnReadPort=USBMON_ReadPort;
  101. lpMonitorInfo->Monitor.pfnEndDocPort=USBMON_EndDocPort;
  102. lpMonitorInfo->Monitor.pfnClosePort=USBMON_ClosePort;
  103. lpMonitorInfo->Monitor.pfnAddPort=NULL; //Obsolete
  104. lpMonitorInfo->Monitor.pfnAddPortEx=NULL; //Obsolete
  105. lpMonitorInfo->Monitor.pfnConfigurePort=NULL; //Obsolete
  106. lpMonitorInfo->Monitor.pfnDeletePort=NULL; //Obsolete
  107. lpMonitorInfo->Monitor.pfnGetPrinterDataFromPort=USBMON_GetPrinterDataFromPort;
  108. lpMonitorInfo->Monitor.pfnSetPortTimeOuts=USBMON_SetPortTimeOuts;
  109. // lpMonitorInfo->Monitor.pfnXcvOpenPort=USBMON_XcvOpenPort;
  110. lpMonitorInfo->Monitor.pfnXcvOpenPort=NULL;
  111. // lpMonitorInfo->Monitor.pfnXcvDataPort=USBMON_XcvDataPort;
  112. lpMonitorInfo->Monitor.pfnXcvDataPort=NULL;
  113. // lpMonitorInfo->Monitor.pfnXcvClosePort=USBMON_XcvClosePort;
  114. lpMonitorInfo->Monitor.pfnXcvClosePort=NULL;
  115. }
  116. else
  117. {
  118. OutputDebugStringD1("USBMON: Error, Out of memory\n");
  119. }
  120. } /*end if reg keys OK*/
  121. else
  122. {
  123. OutputDebugStringD1("USBMON: Error, Unable to get reg keys!\n");
  124. }
  125. GpBaseNameList=NULL;
  126. return lpMonitorInfo;
  127. };
  128. BOOL USBMON_GetPrinterDataFromPort(
  129. HANDLE hPort,
  130. DWORD ControlID,
  131. LPWSTR pValueName,
  132. LPWSTR lpInBuffer,
  133. DWORD cbInBuffer,
  134. LPWSTR lpOutBuffer,
  135. DWORD cbOutBuffer,
  136. LPDWORD lpcbReturned)
  137. {
  138. BOOL bStatus;
  139. PUSBMON_PORT_INFO pPortInfo;
  140. HANDLE hPrinter;
  141. if(ControlID==0)
  142. {
  143. OutputDebugStringD2("USBMON: GetPrinterDataFromPort Control ID==0, bailing. requested value==");
  144. OutputDebugStringWD2(pValueName);
  145. OutputDebugStringD2("\n");
  146. SetLastError(ERROR_INVALID_PARAMETER);
  147. return FALSE; //need to set last error here.
  148. }
  149. pPortInfo=(PUSBMON_PORT_INFO)hPort;
  150. hPrinter=pPortInfo->hPrinter;
  151. OutputDebugStringD3("USBMON: Before DeviceIoControl\n");
  152. bStatus=DeviceIoControl(hPrinter,ControlID,lpInBuffer,cbInBuffer,lpOutBuffer,cbOutBuffer,lpcbReturned,NULL);
  153. if(!bStatus)
  154. {
  155. OutputDebugStringD2("USBMON: USBMON_GetPrinterDataFromPort failing\n");
  156. SetLastError(ERROR_INVALID_PARAMETER);
  157. }
  158. else
  159. {
  160. OutputDebugStringD2("USBMON: USBMON_GetPrinterDataFromPort Success\n");
  161. SetLastError(ERROR_SUCCESS);
  162. }
  163. return bStatus;
  164. } /*end function USBMON_GetPrinterDataFromPort*/
  165. BOOL WINAPI USBMON_OpenPort(LPWSTR pName, PHANDLE pHandle)
  166. {
  167. PUSBMON_PORT_INFO pWalkPorts;
  168. BOOL bFound=FALSE;
  169. OutputDebugStringD2("USBMON: Head of USBMON_OpenPort\n");
  170. pWalkPorts=pPortInfoG;
  171. wsprintfW((WCHAR *)szDebugBuff,L"USBMON: OpenPort Looking for \"%s\"\n",pName);
  172. OutputDebugStringWD2((WCHAR *)szDebugBuff);
  173. while((bFound==FALSE)&&(pWalkPorts!=NULL))
  174. {
  175. wsprintfW((WCHAR *)szDebugBuff,L"USBMON: Looking at node \"%s\"\n",pWalkPorts->szPortName);
  176. OutputDebugStringWD3((WCHAR *)szDebugBuff);
  177. if(lstrcmp(pName,pWalkPorts->szPortName)==0)
  178. bFound=TRUE;
  179. else
  180. pWalkPorts=pWalkPorts->pNext;
  181. }
  182. if(bFound)
  183. {
  184. wsprintfW((WCHAR *)szDebugBuff,L"USBMON: About to open path: \"%s\"\n",pWalkPorts->DevicePath);
  185. OutputDebugStringD3(szDebugBuff);
  186. // pWalkPorts->hDeviceHandle=CreateFile(pWalkPorts->DevicePath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
  187. // if(pWalkPorts->hDeviceHandle!=INVALID_HANDLE_VALUE)
  188. // {
  189. *pHandle=(HANDLE)pWalkPorts;
  190. pWalkPorts->ReadTimeoutMultiplier=0;
  191. pWalkPorts-> ReadTimeoutConstant=60000;
  192. pWalkPorts->WriteTimeoutMultiplier=0;
  193. pWalkPorts->WriteTimeoutConstant=60000;
  194. OutputDebugStringD3("USBMON: USBMON_OpenPort returning TRUE\n");
  195. return TRUE;
  196. // }
  197. }
  198. *pHandle=INVALID_HANDLE_VALUE;
  199. wsprintfA(szDebugBuff,"USBMON: USBMON_OpenPort returning FALSE, error=%d\n",GetLastError());
  200. OutputDebugStringD1(szDebugBuff);
  201. return FALSE;
  202. }
  203. BOOL WINAPI USBMON_StartDocPort(HANDLE hPort, LPWSTR pPrinterName, DWORD JobId, DWORD Level, LPBYTE pDocInfo)
  204. {
  205. BOOL bResult;
  206. HANDLE hPrinter;
  207. PUSBMON_PORT_INFO pPortInfo;
  208. OutputDebugStringD2("USBMON: Head of StartDocPort\n");
  209. pPortInfo=(PUSBMON_PORT_INFO)hPort;
  210. bResult=OpenPrinterW(pPrinterName,&hPrinter,NULL);
  211. if(bResult==FALSE)
  212. {
  213. OutputDebugStringD1("USBMON: OpenPrinter failed\n");
  214. return FALSE;
  215. }
  216. else
  217. {
  218. pPortInfo->hPrinter=hPrinter;
  219. pPortInfo->dwCurrentJob=JobId;
  220. // pWalkPorts->hDeviceHandle=CreateFile(pWalPorts->DevicePath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
  221. wsprintfW((WCHAR *)szDebugBuff,L"USBMON:---------------------------------- About to open path: \"%s\"\n",pPortInfo->DevicePath);
  222. OutputDebugStringD3(szDebugBuff);
  223. // pPortInfo->hDeviceHandle=CreateFile(pPortInfo->DevicePath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
  224. vInterlockedOpenPort(pPortInfo);
  225. OutputDebugStringD3("USBMON: CreateFile in StartDocPort\n");
  226. if(pPortInfo->hDeviceHandle==INVALID_HANDLE_VALUE)
  227. {
  228. OutputDebugStringD1("USBMON: CreateFile on printer device object failed\n");
  229. return FALSE;
  230. }
  231. return TRUE;
  232. } /*end else bResult OK*/
  233. }
  234. BOOL WINAPI USBMON_ReadPort(HANDLE hPort, LPBYTE pBuffer, DWORD cbBuf,LPDWORD pcbWritten)
  235. {
  236. DWORD dwBytesToRead;
  237. PUSBMON_PORT_INFO pPortInfo;
  238. DWORD dwTimeout;
  239. OVERLAPPED rOverlappedInfo;
  240. BOOL bTimeOut=FALSE,bSuccess=TRUE;
  241. OverlappedResults Results;
  242. OutputDebugStringD3("USBMON: Head of ReadPort\n");
  243. pPortInfo=(PUSBMON_PORT_INFO)hPort;
  244. dwBytesToRead=cbBuf;
  245. vInterlockedOpenPort(pPortInfo);
  246. if(pPortInfo->hDeviceHandle==INVALID_HANDLE_VALUE)
  247. {
  248. OutputDebugStringD1("USBMON: CreateFile on printer device object (inside ReadPort) failed\n");
  249. return FALSE;
  250. } /*end else CreateFile failed*/
  251. dwTimeout=(pPortInfo->ReadTimeoutMultiplier)*dwBytesToRead;
  252. dwTimeout+=pPortInfo->ReadTimeoutConstant;
  253. memset(&rOverlappedInfo,0,sizeof(rOverlappedInfo));
  254. rOverlappedInfo.hEvent=(HANDLE)&Results;
  255. if(ReadFileEx(pPortInfo->hDeviceHandle,pBuffer,dwBytesToRead,&rOverlappedInfo,ReadWriteCallback)==FALSE)
  256. {
  257. bSuccess=FALSE;
  258. }
  259. else
  260. {
  261. wsprintfA(szDebugBuff,"USBMON: Sleep time=%d\n",dwTimeout);
  262. OutputDebugStringD3(szDebugBuff);
  263. if(SleepEx(dwTimeout,TRUE)==0)
  264. {
  265. OutputDebugStringD1("USBMON: SleepEx failed or timed out\n");
  266. CancelIo(pPortInfo->hDeviceHandle);
  267. bSuccess=FALSE;
  268. SetLastError(ERROR_TIMEOUT);
  269. }
  270. else
  271. {
  272. if(Results.dwErrorCode==0)
  273. {
  274. wsprintfA(szDebugBuff,"USBMON: bytes read=%u\n",*pcbWritten);
  275. OutputDebugStringD3(szDebugBuff);
  276. SetLastError(ERROR_SUCCESS);
  277. OutputDebugStringD3(szDebugBuff);
  278. }
  279. else
  280. {
  281. OutputDebugStringD1("USBMON: callback reported error\n");
  282. SetLastError(Results.dwErrorCode);
  283. bSuccess=FALSE;
  284. } /*end else callback reported error*/
  285. } /*end else did not time out*/
  286. *pcbWritten=Results.dwBytesTransfered;
  287. } /*end able to start read*/
  288. if(!bSuccess)
  289. {
  290. OutputDebugStringD2("USBMON: Re-opening port\n");
  291. vInterlockedReOpenPort(pPortInfo);
  292. }
  293. vInterlockedClosePort(pPortInfo);
  294. return bSuccess;
  295. } /*end function ReadPort*/
  296. BOOL WINAPI USBMON_WritePort(HANDLE hPort, LPBYTE pBuffer, DWORD cbBuf,LPDWORD pcbWritten)
  297. {
  298. DWORD dwBytesToWrite;
  299. PUSBMON_PORT_INFO pPortInfo;
  300. DWORD dwTimeout;
  301. OVERLAPPED rOverlappedInfo;
  302. BOOL bTimeOut=FALSE,bSuccess=TRUE;
  303. OverlappedResults Results;
  304. OutputDebugStringD3("USBMON: Head of WritePort\n");
  305. pPortInfo=(PUSBMON_PORT_INFO)hPort;
  306. if(cbBuf>MAX_WRITE_CHUNK)
  307. dwBytesToWrite=MAX_WRITE_CHUNK;
  308. else
  309. dwBytesToWrite=cbBuf;
  310. // pPortInfo->hDeviceHandle=CreateFile(pPortInfo->DevicePath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
  311. vInterlockedOpenPort(pPortInfo);
  312. if(pPortInfo->hDeviceHandle==INVALID_HANDLE_VALUE)
  313. {
  314. OutputDebugStringD1("USBMON: CreateFile on printer device object (inside WritePort) failed\n");
  315. return FALSE;
  316. } /*end else CreateFile failed*/
  317. dwTimeout=(pPortInfo->WriteTimeoutMultiplier)*dwBytesToWrite;
  318. dwTimeout+=pPortInfo->WriteTimeoutConstant;
  319. memset(&rOverlappedInfo,0,sizeof(rOverlappedInfo));
  320. rOverlappedInfo.hEvent=(HANDLE)&Results;
  321. //wsprintfA(szDebugBuff,"USBMON:/*dd About to WriteFileEx; pPortInfo->hDeviceHandle=%x, pBuffer=%x, dwBytesToWrite=%x\n",pPortInfo->hDeviceHandle,
  322. // pBuffer,dwBytesToWrite);
  323. //OutputDebugStringD1(szDebugBuff);
  324. if(WriteFileEx(pPortInfo->hDeviceHandle,pBuffer,dwBytesToWrite,&rOverlappedInfo,ReadWriteCallback)==FALSE)
  325. {
  326. bSuccess=FALSE;
  327. }
  328. else
  329. {
  330. wsprintfA(szDebugBuff,"USBMON: Sleep time=%d\n",dwTimeout);
  331. OutputDebugStringD2(szDebugBuff);
  332. if(SleepEx(dwTimeout,TRUE)==0)
  333. {
  334. OutputDebugStringD2("USBMON: SleepEx failed or timed out\n");
  335. CancelIo(pPortInfo->hDeviceHandle);
  336. bSuccess=FALSE;
  337. SetLastError(ERROR_TIMEOUT);
  338. }
  339. else
  340. {
  341. if(Results.dwErrorCode==0)
  342. {
  343. wsprintfA(szDebugBuff,"USBMON: bytes written=%u\n",*pcbWritten);
  344. OutputDebugStringD3(szDebugBuff);
  345. SetLastError(ERROR_SUCCESS);
  346. OutputDebugStringD3(szDebugBuff);
  347. }
  348. else
  349. {
  350. OutputDebugStringD3("USBMON: callback reported error\n");
  351. SetLastError(Results.dwErrorCode);
  352. bSuccess=FALSE;
  353. } /*end else callback reported error*/
  354. } /*end else did not time out*/
  355. *pcbWritten=Results.dwBytesTransfered;
  356. } /*end able to start write*/
  357. if(!bSuccess)
  358. {
  359. OutputDebugStringD2("USBMON: Re-opening port\n");
  360. vInterlockedReOpenPort(pPortInfo);
  361. }
  362. vInterlockedClosePort(pPortInfo);
  363. return bSuccess;
  364. } /*end function WritePort*/
  365. VOID CALLBACK ReadWriteCallback(DWORD dwErrorCode,DWORD dwNumberOfBytesTransfered,LPOVERLAPPED lpOverlapped)
  366. {
  367. pOverlappedResults pResults;
  368. OutputDebugStringD2(" USBMON: ReadWriteCallback\n");
  369. pResults=(pOverlappedResults)(lpOverlapped->hEvent);
  370. pResults->dwErrorCode=dwErrorCode;
  371. pResults->dwBytesTransfered=dwNumberOfBytesTransfered;
  372. } /*end function ReadWriteCallback*/
  373. BOOL WINAPI USBMON_EndDocPort(HANDLE hPort)
  374. {
  375. PUSBMON_PORT_INFO pPortInfo;
  376. OutputDebugStringD3("USBMON: Head of EndDocPort\n");
  377. pPortInfo=(PUSBMON_PORT_INFO)hPort;
  378. SetJob(pPortInfo->hPrinter,pPortInfo->dwCurrentJob,0,NULL,JOB_CONTROL_SENT_TO_PRINTER);
  379. ClosePrinter(pPortInfo->hPrinter);
  380. vInterlockedClosePort(pPortInfo);
  381. return TRUE;
  382. }
  383. BOOL WINAPI USBMON_ClosePort(HANDLE hPort)
  384. {
  385. OutputDebugStringD3("USBMON: Head of ClosePort\n");
  386. // CloseHandle( ((PUSBMON_PORT_INFO)hPort)->hDeviceHandle);
  387. return TRUE;
  388. }
  389. BOOL WINAPI USBMON_SetPortTimeOuts(HANDLE hPort, LPCOMMTIMEOUTS lpCTO, DWORD reserved)
  390. {
  391. PUSBMON_PORT_INFO pPortInfo;
  392. OutputDebugStringD3(" USBMON: Head of SetPortTimeOuts\n");
  393. pPortInfo=(PUSBMON_PORT_INFO)hPort;
  394. wsprintfA(szDebugBuff,"USBMON: SetPortTimeOut, ReadMultiplier=%u, ReadConstant=%u\n",
  395. lpCTO->ReadTotalTimeoutMultiplier,lpCTO->ReadTotalTimeoutConstant);
  396. OutputDebugStringD2(szDebugBuff);
  397. pPortInfo->ReadTimeoutMultiplier=lpCTO->ReadTotalTimeoutMultiplier;
  398. pPortInfo->ReadTimeoutConstant=lpCTO->ReadTotalTimeoutConstant;
  399. pPortInfo->WriteTimeoutMultiplier=lpCTO->WriteTotalTimeoutMultiplier;
  400. pPortInfo->WriteTimeoutConstant=lpCTO->WriteTotalTimeoutConstant;
  401. return TRUE;
  402. }
  403. BOOL WINAPI USBMON_XcvOpenPort(LPCWSTR pszObject, ACCESS_MASK GrantedAccess, PHANDLE phXcv)
  404. {
  405. OutputDebugStringD2("USBMON: Head of XcvOpenPort\n");
  406. return FALSE;
  407. }
  408. DWORD WINAPI USBMON_XcvDataPort(HANDLE hXcv,
  409. LPCWSTR pszDataName,
  410. PBYTE pInputData,
  411. DWORD cbInputData,
  412. PBYTE pOutputData,
  413. DWORD cbOutputData,
  414. PDWORD pcbOutputNeeded)
  415. {
  416. OutputDebugStringD2("USBMON: Head of XcvDataPort\n");
  417. return ERROR_INVALID_FUNCTION;
  418. }
  419. BOOL WINAPI USBMON_XcvClosePort(HANDLE hXcv)
  420. {
  421. OutputDebugStringD2("USBMON: Head of XcvClosePort\n");
  422. return FALSE;
  423. }
  424. /*
  425. AtoI - Convert a string to a signed or unsigned integer
  426. IN pStr = ASCIZ representation of number with optional leading/trailing
  427. whitespace and optional leading '-'.
  428. Radix = Radix to use for conversion (2, 8, 10, or 16)
  429. OUT *pResult = Numeric result, or unchanged on failure
  430. Returns 1 on success, 0 if malformed string.
  431. Note Not reentrant
  432. */
  433. UINT AtoI(PUCHAR pStr, UINT Radix, PUINT pResult)
  434. {
  435. UINT r = 0;
  436. UINT Sign = 0;
  437. UCHAR c;
  438. UINT d;
  439. while (*pStr == ' ' || *pStr == '\t')
  440. pStr++;
  441. if (*pStr == '-') {
  442. Sign = 1;
  443. pStr++;
  444. }
  445. if (*pStr == 0)
  446. return 0; // Empty string!
  447. while ((c = *pStr) != 0 && c != ' ' && c != '\t') {
  448. if (c >= '0' && c <= '9')
  449. d = c - '0';
  450. else if (c >= 'A' && c <= 'F')
  451. d = c - ('A' - 10);
  452. else if (c >= 'a' && c <= 'f')
  453. d = c - ('a' - 10);
  454. else
  455. return 0; // Not a digit
  456. if (d >= Radix)
  457. return 0; // Not in radix
  458. r = r*Radix+d;
  459. pStr++;
  460. }
  461. while (*pStr == ' ' || *pStr == '\t')
  462. pStr++;
  463. if (*pStr != 0)
  464. return 0; // Garbage at end of string
  465. if (Sign)
  466. r = (UINT)(-(INT)r);
  467. *pResult = r;
  468. return 1; // Success!
  469. }
  470. void vLoadBaseNames(HKEY hRegKey, PUSBMON_BASENAME *ppHead)
  471. {
  472. PUSBMON_BASENAME pNew,pWalk;
  473. WCHAR wcName[MAX_PORT_LEN];
  474. int iIndex=0;
  475. LONG lStatus;
  476. LONG lDataSize;
  477. int iCompare;
  478. *ppHead=GlobalAlloc(0,sizeof(USBMON_PORT_INFO));
  479. if(*ppHead==NULL)
  480. return;
  481. (*ppHead)->pNext=NULL;
  482. wcscpy((*ppHead)->wcBaseName,L"USB");
  483. lDataSize=MAX_PORT_LEN;
  484. lStatus=RegEnumValue(hRegKey,iIndex++,wcName,&lDataSize,NULL,NULL,NULL,NULL);
  485. while(lStatus==ERROR_SUCCESS)
  486. {
  487. pNew=GlobalAlloc(0,sizeof(USBMON_PORT_INFO));
  488. if(pNew==NULL)
  489. return;
  490. wcscpy(pNew->wcBaseName,wcName);
  491. if(wcscmp(pNew->wcBaseName,(*ppHead)->wcBaseName)<0)
  492. {
  493. pNew->pNext=*ppHead;
  494. *ppHead=pNew;
  495. } /*end if new first node*/
  496. else
  497. {
  498. pWalk=*ppHead;
  499. iCompare=-1;
  500. while((iCompare<0)&&(pWalk->pNext!=NULL))
  501. {
  502. iCompare=wcscmp(pNew->wcBaseName,pWalk->pNext->wcBaseName);
  503. if(iCompare<0)
  504. pWalk=pWalk->pNext;
  505. } /*end while walk*/
  506. if(iCompare>0)
  507. {
  508. pNew->pNext=pWalk->pNext;
  509. pWalk->pNext=pNew;
  510. }
  511. else if(iCompare==0)
  512. {
  513. GlobalFree(pNew);
  514. } /*end if collision*/
  515. } /*else not new first node*/
  516. lDataSize=MAX_PORT_LEN;
  517. lStatus=lStatus=RegEnumValue(hRegKey,iIndex++,wcName,&lDataSize,NULL,NULL,NULL,NULL);
  518. } //end while more reg items
  519. } //end function vLoadBaseNames
  520. void vInterlockedOpenPort(PUSBMON_PORT_INFO pPortInfo)
  521. {
  522. OutputDebugStringD2("USBMON: Head of vInterlockedOpenPort\n");
  523. WaitForSingleObjectEx(hReadWriteSemaphore,INFINITE,FALSE);
  524. if((pPortInfo->iRefCount==0)||(pPortInfo->hDeviceHandle==INVALID_HANDLE_VALUE))
  525. {
  526. OutputDebugStringD3("USBMON: vInterlockedOpenPort, Really opening:");
  527. OutputDebugStringWD3(pPortInfo->DevicePath);
  528. OutputDebugStringD3("\n");
  529. pPortInfo->hDeviceHandle=CreateFile(pPortInfo->DevicePath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
  530. if(pPortInfo->hDeviceHandle!=INVALID_HANDLE_VALUE)
  531. (pPortInfo->iRefCount)++;
  532. }
  533. else
  534. {
  535. OutputDebugStringD3("USBMON: vInterlockedOpenPort, Just incrementing ref count\n");
  536. (pPortInfo->iRefCount)++;
  537. }
  538. wsprintfA(szDebugBuff,"USBMON: vInterlockedOpenPort, iRefCount=%d\n",pPortInfo->iRefCount);
  539. OutputDebugStringD2(szDebugBuff);
  540. ReleaseSemaphore(hReadWriteSemaphore,1,NULL);
  541. } /*end function vInterlockedOpenPort*/
  542. void vInterlockedClosePort(PUSBMON_PORT_INFO pPortInfo)
  543. {
  544. OutputDebugStringD2("USBMON: Head of vInterlockedClosePort\n");
  545. WaitForSingleObjectEx(hReadWriteSemaphore,INFINITE,FALSE);
  546. (pPortInfo->iRefCount)--;
  547. if(pPortInfo<0) {
  548. DebugBreak();
  549. pPortInfo=0;
  550. }
  551. if(pPortInfo->iRefCount==0)
  552. {
  553. CloseHandle(pPortInfo->hDeviceHandle);
  554. pPortInfo->hDeviceHandle=INVALID_HANDLE_VALUE;
  555. }
  556. wsprintfA(szDebugBuff,"USBMON: vInterlockedClosePort, iRefCount=%d\n",pPortInfo->iRefCount);
  557. OutputDebugStringD2(szDebugBuff);
  558. ReleaseSemaphore(hReadWriteSemaphore,1,NULL);
  559. } /*end function vInterlockedClosePort*/
  560. void vInterlockedReOpenPort(PUSBMON_PORT_INFO pPortInfo)
  561. {
  562. OutputDebugStringD2("USBMON: Head of vInterlockedReOpenPort\n");
  563. WaitForSingleObjectEx(hReadWriteSemaphore,INFINITE,FALSE);
  564. //
  565. // big problem. what if another thread is using the handle
  566. //
  567. CloseHandle(pPortInfo->hDeviceHandle);
  568. OutputDebugStringD3("USBMON: vInterlockedReOpenPort, Really opening----------------------------------------------:\n");
  569. OutputDebugStringWD3(pPortInfo->DevicePath);
  570. OutputDebugStringD3("\n");
  571. pPortInfo->hDeviceHandle=CreateFile(pPortInfo->DevicePath,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
  572. if(pPortInfo->hDeviceHandle==INVALID_HANDLE_VALUE)
  573. // --pPortInfo->iRefCount;
  574. wsprintfA(szDebugBuff,"USBMON: vInterlockedReOpenPort, iRefcCount=%d\n",pPortInfo->iRefCount);
  575. OutputDebugStringD2(szDebugBuff);
  576. ReleaseSemaphore(hReadWriteSemaphore,1,NULL);
  577. } /*end function vInterlockedReOpenPort*/