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.

416 lines
8.2 KiB

  1. Notes on DynaMon:
  2. Starts w/ DisableThreadCalls
  3. InitializePrintMonitor:
  4. Simply a Port MOn
  5. Fill out MonitorEx
  6. Build CritSecs
  7. EnumPorts:
  8. Get the EnumIndex
  9. Load SetupAPI stuff
  10. Enter CritSec
  11. If we haven't completed a previous Enum do another one
  12. WalkPortList
  13. else keep track of skipped enums
  14. Build the List to return
  15. Check Level & Figure Size
  16. If big enough buffer
  17. build each port info struct
  18. Give the new list to the Background Thread (PassPortUpdateListToBT)
  19. Leave CritSec
  20. Unload SetupAPI
  21. UpdateNumber of Enumports
  22. WalkPortList:
  23. Re-Enter CtitSec
  24. Return Security to System
  25. Get a list of USB Printers (And Dot4 & SCSIPrnt & Parallel)
  26. Go through the list one at a time
  27. Get the device deatil
  28. See if the port is active
  29. If inactive & already in list skip it
  30. If active & status is the same skip it
  31. Process the port (ProcessPortInfo)
  32. Loop
  33. Exit the CritSec
  34. Destroy the DevList
  35. Impersonate the Client
  36. ProcessPortInfo:
  37. First Get the PortName & Open the DevNode (GetPortNameAndRegKey)
  38. If we can't find a RegKey or Port Number
  39. Add to list as Useless Entry & return (AddUselessPortEntry)
  40. Find Port in the List (FindPort)
  41. If it is in list & it changed
  42. Update it's info (UpdatePortInfo)
  43. If not in list
  44. Add it (AddPortToList)
  45. GetPortNameAndRegKey:
  46. Try to Open Device Intf. RegKey
  47. If fails return invalid handle
  48. Now get the port NUmber from the Reg
  49. If this fails return Invalid Handle
  50. Get Base Name from Reg
  51. Buld the Port Name
  52. Return hRegKey & PortName
  53. AddUselessPortEntry:
  54. See if the port is already in the Useless List (FindUselessPortEntry)
  55. If found don't add it
  56. Create a useless Port Entry & insert it in the list
  57. FindPort:
  58. Enter CritSec
  59. Search list looking for portname match
  60. Stop if name matches or is greater
  61. If no match return NULL.
  62. Still return pointer to previous space in list
  63. Exit CritSec
  64. UpdatePortInfo:
  65. Get new DevicePath & Port Description
  66. If DEviceFlags ahve changed
  67. Store new Flags
  68. Add this to UpdateList (AddToPortUpdateList)
  69. AddPortToList:
  70. Alloc Mem for new PortInfo
  71. Copy in all pertinent info
  72. Add to the good port list
  73. Check if this is also in the Useless port list (FindUselessEntry)
  74. If in USeless List fix pointers, free mem, & dec count
  75. Add to Update list
  76. Inc port count
  77. FindUselessPortEntry:
  78. Search UselessList for matching portname
  79. If found return pointer to current & previous entries.
  80. AddToPortUpdateList:
  81. Create an UPDATE_INFO & fill in
  82. Add new info to front of the list
  83. PassPortUpdateListToBT:
  84. Check if any update threads currently
  85. NO:
  86. Create a new thread and give it the list
  87. One:
  88. Create a backup thread and give it new list
  89. Two:
  90. Add these update port to the list of 2nd thread
  91. CreateBTAndReturnEvent:
  92. Create a new event
  93. Create a new occurance of BackgroundThread
  94. BackgroundThread:
  95. Wait for Trigger
  96. Get Update List & CritSec
  97. Get list fo all local printers
  98. Process the update list
  99. Check if portname is used by spooler
  100. OpenPort:
  101. Find the port in our List (FindPort)
  102. If Found
  103. Init CritSEc & Return Handle
  104. ClosePort:
  105. Delete CritSec
  106. StarDocPort:
  107. Open the Printer (OpenPrinter)
  108. Save JobId
  109. Actually open the device port (LocalOpenPort)
  110. If it fails
  111. CLose the printer
  112. else
  113. Set StartDoc Flag
  114. LocalOpenPort:
  115. Enter Port CritSec
  116. If Handle is Invalid
  117. If we have a ref count exit
  118. Open a handle to the device
  119. If this fails with FILE_NOT_FOUND
  120. Try to rebuild the stack for Dot4 (DOT4PNP)
  121. If success create an event for Overlapped I/O
  122. Bump Ref Count
  123. Leave Port Critsec
  124. Dot4PnP:
  125. Make sure it is a Dot4 device
  126. Load Config Manager DLL
  127. Revert to System
  128. Force PnP on parallel port
  129. Impersonte User
  130. Try to open the device again
  131. Free CM DLL
  132. EndDocPort:
  133. If all data has not been sent
  134. If job should aborted (AbortThisJob)
  135. If data is currently scheduled
  136. Cancel the write
  137. Get the write status
  138. Not Abort but still data scheduled
  139. get status of last right
  140. else
  141. wait a sec
  142. reschedule current write
  143. If job shoudl be restarted (NeedToResubmitJob)
  144. Invalidate Port (InvalidatePortHandle)
  145. Set job control to restart
  146. exit loop
  147. Until all data sent
  148. Free up the data buffers (FreeWriteBuffer)
  149. Turn off StartDoc flag
  150. Close the port handle (LocalClosePort)
  151. show all data sent
  152. Close the printer
  153. AbortThisJob:
  154. Get current Job Info
  155. If status is bad (Deleting,Deleted,Restart)
  156. return TRUE
  157. NeedToResubmitJob:
  158. Compare Error passed in with list of failure codes...
  159. If match return TRUE
  160. InvalidatePortHandle:
  161. Close the Device & Overlap Event
  162. Reset Pointers
  163. Free data (FreeWRiteBuffer)
  164. FreeWriteBuffer:
  165. Free memory & reset size args
  166. LocalClosePort:
  167. Enter Port Critsec
  168. Dec Ref Count
  169. If still open end (cRef > 0)
  170. Close Device & Event
  171. Exit Critsec
  172. WritePort:
  173. Set write timeout
  174. For USB tweak Buffersize down to 4K
  175. If device closed
  176. restart Job
  177. Fail call w/ Cancelled
  178. Try to Open Port (LocalOpenPort)
  179. If failed return
  180. while still old data to be sent
  181. If already scheduled
  182. check status (GetTimeLeft)
  183. (ScheduleWriteStatus
  184. else
  185. Schedule it (ScheduleWrite)
  186. Any errors Fail out
  187. If we have too much data for our current buffer
  188. Free current (FreeWriteBuffer)
  189. Allocate a new one...
  190. Copy the Data to our buffer
  191. while still new data to be sent
  192. If already scheduled
  193. check status (GetTimeLeft)
  194. (ScheduleWriteStatus
  195. else
  196. Schedule it (ScheduleWrite)
  197. Any errors Fail out
  198. If this is a write outside a StartDoc (LM write)
  199. Don't let any writes carry over (CancelIO)
  200. Get the status of write (ScheduledWriteStatus)
  201. Set amount writtne & free buffer
  202. If some data was written or scheduled
  203. tell spooler all was writtne
  204. else
  205. free the buffer
  206. Done:
  207. Check if job needs to be restarted (NeedToResubmitJob)
  208. If so invalidate the port
  209. else if we failed due to timeout
  210. Get the port status (GetLptStatus)
  211. Close theport (LocalClosePort)
  212. ScheduleWrite:
  213. Shouldn't be any data scheduled or not completed
  214. Schedule any data not sent
  215. Call Write of schduleded data (WriteFile)
  216. If write failed
  217. If LastError is success
  218. set to unknown
  219. else if IO_PENDING
  220. set to success
  221. If LastError not Success
  222. Show that no data was scheduled
  223. Return LastError
  224. GetTimeLeft:
  225. If the current timeout is the MAX
  226. reutn the MAX
  227. Get current Time
  228. Compare if Timeout ha expired
  229. If yes then return 0
  230. Else
  231. return how much time left until timeout expires.
  232. ScheduledWriteStatus:
  233. Wait for Overlapped Event to signal
  234. If timed out
  235. Return Timeout error
  236. Get Result
  237. Reset the Overlap Event
  238. Update the amount completed by the amount written
  239. Clear amount scheduled since no write pending
  240. return LastError
  241. GetLPTStatus:
  242. Create Overlap Event
  243. Send a USBPRINT IOCTL to get the parallel status
  244. If status returned set the status byte
  245. else set a benign status
  246. Close the Event
  247. SetPortTimeouts:
  248. Save data in TO struct
  249. ReadPort:
  250. Create a new Read Handle & Overlap struct
  251. Do a ReadFile on Handle
  252. Wait for OVerlap Event
  253. If Event Timed Out
  254. Cancel Read
  255. Get Result
  256. If failure return no data read
  257. Close Event & Read Handle
  258. GetPrinterDataFomrPort:
  259. If not ControlID fail
  260. Create Overlap Event
  261. Open the Port (LocalOpenPort)
  262. If IOCTL = QUERY_DEVICE_ID