title: startdocprinter returns bad non-zero print queue JobID. It's invalid and decreases on subsequent runs
body: <p>I'm using a slightly modified version of the vb.net/win32 example of the MSKB RawPrinterHelper code to send RAW print jobs to the print queue. </p>
  
  <p>Everything works perfectly, It spools, it prints, and generally life is good, however the ID I get back from  StartDocPrinter cannot be used to lookup the print job status. It's just wrong.</p>
  
  <p>The JobID needed to lookup the Job Status with ManagementObjectSearcher does not match the ID returned by StartDocPrinter.</p>
  
  <p>Even more strange, is that StartDocPrinter returns a handle that <em>decreases</em> each time it's called.</p>
  
  <p>It looks almost like some sort of signed/unsigned overflow condition.</p>
  
  <p>One thing I've considered, that I can't seem to find a reference for, is that StartDocPrinter and "everything else" does not return/use the same JobID, but I haven't found a definitive reference or a way to convert between them.</p>
  
  <p>Any help is appreciated!</p>
  
  <p>Terry</p>
  
  <p><strong>EDIT</strong></p>
  
  <p><strong>WEIRDNESS-LEVEL: Infinite</strong></p>
  
  <p>I wrote an app to monitor the print queue and continuously return a list of PrintSystemJobInfo.JobIdentifiers from the print queue.</p>
  
  <p>While the print job is spooling, it has an ID that's in the 29,000 range, and each new job <em>decrements</em> it by one. HOWEVER . . . .</p>
  
  <p>Once the job has finished spooling, the PrintSystemJobInfo.JobIdentifier <em>changes</em> and becomes a "normal" JobIdentifier in the 200 range, in increasing sequence, right inline with all the other jobs.</p>
  
  <p>What I have learned is that my declaration seems to be fine and the JobIdentifier actually changes when the job finishes spooling.</p>
  
  <p>?????</p>
  
  <p>`</p>
  
  <pre><code>&lt;StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)&gt; _
  Structure DOCINFOW
      &lt;MarshalAs(UnmanagedType.LPWStr)&gt; Public pDocName As String
      &lt;MarshalAs(UnmanagedType.LPWStr)&gt; Public pOutputFile As String
      &lt;MarshalAs(UnmanagedType.LPWStr)&gt; Public pDataType As String
  End Structure
  
  &lt;DllImport("winspool.Drv", EntryPoint:="StartDocPrinterW", _
     SetLastError:=True, CharSet:=CharSet.Unicode, _
     ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)&gt; _
  Public Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal level As Int32, ByRef pDI As DOCINFOW) As UInt32
  End Function
  
  
  Public Shared Function SendBytesToPrinter(ByVal szPrinterName As String, ByVal pBytes As IntPtr, ByVal dwCount As Int32, JobName As String) As UInteger
  
      Dim hPrinter As IntPtr
      Dim dwError As Int32
      Dim di As New DOCINFOW
  
      Dim dwWritten As Int32
      Dim pjID As UInteger = 0
  
      Dim PrintQueueName As String = ""
      Dim PrintServerName As String = ""
  
      Try
          Dim pd As New PRINTER_DEFAULTS
  
          With di
              .pDocName = JobName
              .pDataType = "RAW"
          End With
  
          If OpenPrinter(szPrinterName, hPrinter, pd) Then  
              pjID = StartDocPrinter(hPrinter, 1, di)
              If pjID = 0 Then
                ' it's an error. 
              Else
                      If StartPagePrinter(hPrinter) Then
                          If WritePrinter(hPrinter, pBytes, dwCount, dwWritten) = False Then
                              dwError = Marshal.GetLastWin32Error()
  
                          End If
                          EndPagePrinter(hPrinter)
                      End If
                  End If
                  EndDocPrinter(hPrinter)
              End If
              ClosePrinter(hPrinter)
          End If
  
      Return pjID
  End Function
  </code></pre>
  
  <p>`</p>