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

Notes on DynaMon:
Starts w/ DisableThreadCalls
InitializePrintMonitor:
Simply a Port MOn
Fill out MonitorEx
Build CritSecs
EnumPorts:
Get the EnumIndex
Load SetupAPI stuff
Enter CritSec
If we haven't completed a previous Enum do another one
WalkPortList
else keep track of skipped enums
Build the List to return
Check Level & Figure Size
If big enough buffer
build each port info struct
Give the new list to the Background Thread (PassPortUpdateListToBT)
Leave CritSec
Unload SetupAPI
UpdateNumber of Enumports
WalkPortList:
Re-Enter CtitSec
Return Security to System
Get a list of USB Printers (And Dot4 & SCSIPrnt & Parallel)
Go through the list one at a time
Get the device deatil
See if the port is active
If inactive & already in list skip it
If active & status is the same skip it
Process the port (ProcessPortInfo)
Loop
Exit the CritSec
Destroy the DevList
Impersonate the Client
ProcessPortInfo:
First Get the PortName & Open the DevNode (GetPortNameAndRegKey)
If we can't find a RegKey or Port Number
Add to list as Useless Entry & return (AddUselessPortEntry)
Find Port in the List (FindPort)
If it is in list & it changed
Update it's info (UpdatePortInfo)
If not in list
Add it (AddPortToList)
GetPortNameAndRegKey:
Try to Open Device Intf. RegKey
If fails return invalid handle
Now get the port NUmber from the Reg
If this fails return Invalid Handle
Get Base Name from Reg
Buld the Port Name
Return hRegKey & PortName
AddUselessPortEntry:
See if the port is already in the Useless List (FindUselessPortEntry)
If found don't add it
Create a useless Port Entry & insert it in the list
FindPort:
Enter CritSec
Search list looking for portname match
Stop if name matches or is greater
If no match return NULL.
Still return pointer to previous space in list
Exit CritSec
UpdatePortInfo:
Get new DevicePath & Port Description
If DEviceFlags ahve changed
Store new Flags
Add this to UpdateList (AddToPortUpdateList)
AddPortToList:
Alloc Mem for new PortInfo
Copy in all pertinent info
Add to the good port list
Check if this is also in the Useless port list (FindUselessEntry)
If in USeless List fix pointers, free mem, & dec count
Add to Update list
Inc port count
FindUselessPortEntry:
Search UselessList for matching portname
If found return pointer to current & previous entries.
AddToPortUpdateList:
Create an UPDATE_INFO & fill in
Add new info to front of the list
PassPortUpdateListToBT:
Check if any update threads currently
NO:
Create a new thread and give it the list
One:
Create a backup thread and give it new list
Two:
Add these update port to the list of 2nd thread
CreateBTAndReturnEvent:
Create a new event
Create a new occurance of BackgroundThread
BackgroundThread:
Wait for Trigger
Get Update List & CritSec
Get list fo all local printers
Process the update list
Check if portname is used by spooler
OpenPort:
Find the port in our List (FindPort)
If Found
Init CritSEc & Return Handle
ClosePort:
Delete CritSec
StarDocPort:
Open the Printer (OpenPrinter)
Save JobId
Actually open the device port (LocalOpenPort)
If it fails
CLose the printer
else
Set StartDoc Flag
LocalOpenPort:
Enter Port CritSec
If Handle is Invalid
If we have a ref count exit
Open a handle to the device
If this fails with FILE_NOT_FOUND
Try to rebuild the stack for Dot4 (DOT4PNP)
If success create an event for Overlapped I/O
Bump Ref Count
Leave Port Critsec
Dot4PnP:
Make sure it is a Dot4 device
Load Config Manager DLL
Revert to System
Force PnP on parallel port
Impersonte User
Try to open the device again
Free CM DLL
EndDocPort:
If all data has not been sent
If job should aborted (AbortThisJob)
If data is currently scheduled
Cancel the write
Get the write status
Not Abort but still data scheduled
get status of last right
else
wait a sec
reschedule current write
If job shoudl be restarted (NeedToResubmitJob)
Invalidate Port (InvalidatePortHandle)
Set job control to restart
exit loop
Until all data sent
Free up the data buffers (FreeWriteBuffer)
Turn off StartDoc flag
Close the port handle (LocalClosePort)
show all data sent
Close the printer
AbortThisJob:
Get current Job Info
If status is bad (Deleting,Deleted,Restart)
return TRUE
NeedToResubmitJob:
Compare Error passed in with list of failure codes...
If match return TRUE
InvalidatePortHandle:
Close the Device & Overlap Event
Reset Pointers
Free data (FreeWRiteBuffer)
FreeWriteBuffer:
Free memory & reset size args
LocalClosePort:
Enter Port Critsec
Dec Ref Count
If still open end (cRef > 0)
Close Device & Event
Exit Critsec
WritePort:
Set write timeout
For USB tweak Buffersize down to 4K
If device closed
restart Job
Fail call w/ Cancelled
Try to Open Port (LocalOpenPort)
If failed return
while still old data to be sent
If already scheduled
check status (GetTimeLeft)
(ScheduleWriteStatus
else
Schedule it (ScheduleWrite)
Any errors Fail out
If we have too much data for our current buffer
Free current (FreeWriteBuffer)
Allocate a new one...
Copy the Data to our buffer
while still new data to be sent
If already scheduled
check status (GetTimeLeft)
(ScheduleWriteStatus
else
Schedule it (ScheduleWrite)
Any errors Fail out
If this is a write outside a StartDoc (LM write)
Don't let any writes carry over (CancelIO)
Get the status of write (ScheduledWriteStatus)
Set amount writtne & free buffer
If some data was written or scheduled
tell spooler all was writtne
else
free the buffer
Done:
Check if job needs to be restarted (NeedToResubmitJob)
If so invalidate the port
else if we failed due to timeout
Get the port status (GetLptStatus)
Close theport (LocalClosePort)
ScheduleWrite:
Shouldn't be any data scheduled or not completed
Schedule any data not sent
Call Write of schduleded data (WriteFile)
If write failed
If LastError is success
set to unknown
else if IO_PENDING
set to success
If LastError not Success
Show that no data was scheduled
Return LastError
GetTimeLeft:
If the current timeout is the MAX
reutn the MAX
Get current Time
Compare if Timeout ha expired
If yes then return 0
Else
return how much time left until timeout expires.
ScheduledWriteStatus:
Wait for Overlapped Event to signal
If timed out
Return Timeout error
Get Result
Reset the Overlap Event
Update the amount completed by the amount written
Clear amount scheduled since no write pending
return LastError
GetLPTStatus:
Create Overlap Event
Send a USBPRINT IOCTL to get the parallel status
If status returned set the status byte
else set a benign status
Close the Event
SetPortTimeouts:
Save data in TO struct
ReadPort:
Create a new Read Handle & Overlap struct
Do a ReadFile on Handle
Wait for OVerlap Event
If Event Timed Out
Cancel Read
Get Result
If failure return no data read
Close Event & Read Handle
GetPrinterDataFomrPort:
If not ControlID fail
Create Overlap Event
Open the Port (LocalOpenPort)
If IOCTL = QUERY_DEVICE_ID