EnumPrintersA implementation

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

EnumPrintersA implementation

Carl Gundel-2
Here is an implementation of Printer class>>printerNames which uses the
EnumPrintersA API call to get the names of all network and local printers.

-Carl Gundel

DynamicLinkLibrary variableByteSubclass: #WinspoolDLL
  classVariableNames: ''
  poolDictionaries: ''   !



!WinspoolDLL class methods !

fileName
    ^'winspool.drv'
! !



!WinspoolDLL methods !

enumPrinters: flags name: name level: level enumBuf: enum sizeBuf: size
pNeeded: needed pReturned: returned

    <api: 'EnumPrintersA' long long long long long struct struct
ulongReturn>
    ^self invalidArgument!

setDefaultPrinter: name

    <api: 'SetDefaultPrinterA' struct boolean>
    ^self invalidArgument
! !

! KernelDLL methods !

localAlloc: flags bytes: bytes
    <api: LocalAlloc ulong ulong ulongReturn>
    ^self invalidArgument! !

! KernelDLL methods !

localLock: aHandle
    <api: LocalLock ulong ulongReturn>
    ^self invalidArgument! !

! KernelDLL methods !

localReAlloc: hOldMem flags: flags bytes: bytes
    <api: LocalReAlloc ulong ulong ulong ulongReturn>
    ^self invalidArgument! !

! KernelDLL methods !

rtlMoveMemory: printerInfo buffer: buffer length: printerInfoLength
    <api: RtlMoveMemory struct ulong ulong none>
    ^self invalidArgument! !

! WinspoolDLL methods !

enumPrinters: flags name: name level: level enumBuf: enum sizeBuf: size
pNeeded: needed pReturned: returned

    <api: 'EnumPrintersA' long long long long long struct struct
ulongReturn>
    ^self invalidArgument! !

! KernelDLL methods !

localReAlloc: hOldMem length: bufferSize flags: flags
    <api: LocalReAlloc ulong ulong ulong ulongReturn>
    ^self invalidArgument! !

! Printer class methods !

getNetworkPrinterNames
"use the Winspool.dll EnumPrinters API to get the network printer names."
    ^self enumPrinters: self printerEnumConnections! !

! Printer class methods !

getPrinterNames
"use the Winspool.dll EnumPrinters API to get the printer names"
    ^self getLocalPrinterNames, self getNetworkPrinterNames! !

"
Printer getPrinterNames
"! !

! Printer class methods !

getLocalPrinterNames
"use the Winspool.dll EnumPrinters API to get the local printer names."
    ^self enumPrinters: self printerEnumLocal! !

! Printer class methods !

pcReturnedStruct
"This specifies a structure that we use to get the printer name when using
the EnumPrinters API"

    SelfDefinedStructure
        define: 'PCRETURNED'
        withFields: ( IdentityDictionary new
            at: #value put: #( 0 #ulong #yourself );
            yourself ).
    ^SelfDefinedStructure named: 'PCRETURNED'! !

! Printer class methods !

printerEnumLocal
"This flag specifies that we want names of local printers when using
EnumPrinters"
    ^2! !

! Printer class methods !

printerEnumConnections
"This flag specifies that we want names of network printers when using
EnumPrinters"
    ^4! !

! Printer class methods !

printerInfoLevel
"This specifies which kind of information we expect back from EnumPrinters"
    ^4! !

! Printer class methods !

printerInfoLength
"Return the size of the printer info struct."
    ^(SelfDefinedStructure named: 'PRINTERINFO4') size! !

! Printer class methods !

pcbNeededStruct
"This specifies a structure that we use to get the printer name when using
the EnumPrinters API"
    SelfDefinedStructure
        define: 'PCBNEEDED'
        withFields: ( IdentityDictionary new
            at: #value put: #( 0 #ulong #yourself );
            yourself ).
    ^SelfDefinedStructure named: 'PCBNEEDED'! !

! Printer class methods !

kernelMemMoveable
"Used in a call to allocate memory for getting printer names"
        "_LMEM_MOVEABLE = 2"
    ^2! !

! Printer class methods !

kernelMemZeroinit
"Used in a call to allocate memory for getting printer names"
        "_LMEM_ZEROINIT = 64"
    ^64! !

! Printer class methods !

printerInfo4Struct
"This specifies a structure that we use to get the printer name when using
the EnumPrinters API"
    SelfDefinedStructure
        define: 'PRINTERINFO4'
        withFields: ( IdentityDictionary new
            at: #ptrPrinterName put: #( 0 #struct #yourself );
            at: #ptrServerName put: #( 4 #struct #yourself );
            at: #attributes put: #( 8 #ulong #yourself);
            yourself ).
    ^SelfDefinedStructure named: 'PRINTERINFO4'! !

! Printer class methods !

enumPrinters: flags
"Use the Winspool.dll EnumPrinters API to get the list of printers as
specified by flags."
    | pcbNeeded pcReturned printerInfo uFlags hMem pBuffer result count
pointer printers movingPointer hOldMem |
    pcbNeeded := self pcbNeededStruct.
    pcReturned := self pcReturnedStruct.
    printerInfo := self printerInfo4Struct.
    uFlags := self kernelMemMoveable | self kernelMemZeroinit.
    hMem := KernelLibrary localAlloc: uFlags bytes: self printerInfoLength
* 250.  "good for 250 printer names"
    pBuffer := KernelLibrary localLock: hMem.
    result := WinspoolDLL current
        enumPrinters: flags
        name: 0
        level: self printerInfoLevel
        enumBuf: pBuffer
        sizeBuf: self printerInfoLength * 250  "good for 250 printer names"
        pNeeded: pcbNeeded asParameter
        pReturned: pcReturned asParameter.
    result = 0 ifTrue: [ self osError ].
    count := pcReturned value.
    movingPointer := pBuffer.
    printers := OrderedCollection new.
    0 to: count - 1 do: [ :i |
        KernelLibrary
            rtlMoveMemory: printerInfo
            buffer: movingPointer
            length: self printerInfoLength.
        movingPointer := movingPointer + self printerInfoLength.
        pointer := printerInfo addressAtOffset: 0.
        printers add: (String fromAddress: pointer)
    ].
    KernelLibrary localFree: hMem.
    ^printers

"
  Printer enumPrinters: 0
"! !



! Printer class methods !

printerNames
"Answer a collection of all known printer names."
"use getPrinterNames which uses Winspool.dll EnumPrintersA"
    ^self getPrinterNames! !

***           this signature added by listserv             ***
*** Visit  http://www.listserv.dfn.de/archives/vswe-l.html ***
*** for archive browsing and VSWE-L membership management  ***
Reply | Threaded
Open this post in threaded view
|

Re: EnumPrintersA implementation

Henrik Høyer
Hi Carl

Thanks for sharing!

--
Henrik Høyer
Chief Software Architect
[hidden email] * (+45) 4029 2092
Tigervej 27 * 4600 Køge
www.sPeople.dk * (+45) 7023 7775

-----Original Message-----
From: Using Visual Smalltalk for Windows/Enterprise [mailto:[hidden email]] On Behalf Of Carl Gundel
Sent: 13. december 2013 21:57
To: [hidden email]
Subject: EnumPrintersA implementation

Here is an implementation of Printer class>>printerNames which uses the EnumPrintersA API call to get the names of all network and local printers.

-Carl Gundel

DynamicLinkLibrary variableByteSubclass: #WinspoolDLL
  classVariableNames: ''
  poolDictionaries: ''   !



!WinspoolDLL class methods !

fileName
    ^'winspool.drv'
! !



!WinspoolDLL methods !

enumPrinters: flags name: name level: level enumBuf: enum sizeBuf: size
pNeeded: needed pReturned: returned

    <api: 'EnumPrintersA' long long long long long struct struct
ulongReturn>
    ^self invalidArgument!

setDefaultPrinter: name

    <api: 'SetDefaultPrinterA' struct boolean>
    ^self invalidArgument
! !

! KernelDLL methods !

localAlloc: flags bytes: bytes
    <api: LocalAlloc ulong ulong ulongReturn>
    ^self invalidArgument! !

! KernelDLL methods !

localLock: aHandle
    <api: LocalLock ulong ulongReturn>
    ^self invalidArgument! !

! KernelDLL methods !

localReAlloc: hOldMem flags: flags bytes: bytes
    <api: LocalReAlloc ulong ulong ulong ulongReturn>
    ^self invalidArgument! !

! KernelDLL methods !

rtlMoveMemory: printerInfo buffer: buffer length: printerInfoLength
    <api: RtlMoveMemory struct ulong ulong none>
    ^self invalidArgument! !

! WinspoolDLL methods !

enumPrinters: flags name: name level: level enumBuf: enum sizeBuf: size
pNeeded: needed pReturned: returned

    <api: 'EnumPrintersA' long long long long long struct struct
ulongReturn>
    ^self invalidArgument! !

! KernelDLL methods !

localReAlloc: hOldMem length: bufferSize flags: flags
    <api: LocalReAlloc ulong ulong ulong ulongReturn>
    ^self invalidArgument! !

! Printer class methods !

getNetworkPrinterNames
"use the Winspool.dll EnumPrinters API to get the network printer names."
    ^self enumPrinters: self printerEnumConnections! !

! Printer class methods !

getPrinterNames
"use the Winspool.dll EnumPrinters API to get the printer names"
    ^self getLocalPrinterNames, self getNetworkPrinterNames! !

"
Printer getPrinterNames
"! !

! Printer class methods !

getLocalPrinterNames
"use the Winspool.dll EnumPrinters API to get the local printer names."
    ^self enumPrinters: self printerEnumLocal! !

! Printer class methods !

pcReturnedStruct
"This specifies a structure that we use to get the printer name when using the EnumPrinters API"

    SelfDefinedStructure
        define: 'PCRETURNED'
        withFields: ( IdentityDictionary new
            at: #value put: #( 0 #ulong #yourself );
            yourself ).
    ^SelfDefinedStructure named: 'PCRETURNED'! !

! Printer class methods !

printerEnumLocal
"This flag specifies that we want names of local printers when using EnumPrinters"
    ^2! !

! Printer class methods !

printerEnumConnections
"This flag specifies that we want names of network printers when using EnumPrinters"
    ^4! !

! Printer class methods !

printerInfoLevel
"This specifies which kind of information we expect back from EnumPrinters"
    ^4! !

! Printer class methods !

printerInfoLength
"Return the size of the printer info struct."
    ^(SelfDefinedStructure named: 'PRINTERINFO4') size! !

! Printer class methods !

pcbNeededStruct
"This specifies a structure that we use to get the printer name when using the EnumPrinters API"
    SelfDefinedStructure
        define: 'PCBNEEDED'
        withFields: ( IdentityDictionary new
            at: #value put: #( 0 #ulong #yourself );
            yourself ).
    ^SelfDefinedStructure named: 'PCBNEEDED'! !

! Printer class methods !

kernelMemMoveable
"Used in a call to allocate memory for getting printer names"
        "_LMEM_MOVEABLE = 2"
    ^2! !

! Printer class methods !

kernelMemZeroinit
"Used in a call to allocate memory for getting printer names"
        "_LMEM_ZEROINIT = 64"
    ^64! !

! Printer class methods !

printerInfo4Struct
"This specifies a structure that we use to get the printer name when using the EnumPrinters API"
    SelfDefinedStructure
        define: 'PRINTERINFO4'
        withFields: ( IdentityDictionary new
            at: #ptrPrinterName put: #( 0 #struct #yourself );
            at: #ptrServerName put: #( 4 #struct #yourself );
            at: #attributes put: #( 8 #ulong #yourself);
            yourself ).
    ^SelfDefinedStructure named: 'PRINTERINFO4'! !

! Printer class methods !

enumPrinters: flags
"Use the Winspool.dll EnumPrinters API to get the list of printers as specified by flags."
    | pcbNeeded pcReturned printerInfo uFlags hMem pBuffer result count pointer printers movingPointer hOldMem |
    pcbNeeded := self pcbNeededStruct.
    pcReturned := self pcReturnedStruct.
    printerInfo := self printerInfo4Struct.
    uFlags := self kernelMemMoveable | self kernelMemZeroinit.
    hMem := KernelLibrary localAlloc: uFlags bytes: self printerInfoLength
* 250.  "good for 250 printer names"
    pBuffer := KernelLibrary localLock: hMem.
    result := WinspoolDLL current
        enumPrinters: flags
        name: 0
        level: self printerInfoLevel
        enumBuf: pBuffer
        sizeBuf: self printerInfoLength * 250  "good for 250 printer names"
        pNeeded: pcbNeeded asParameter
        pReturned: pcReturned asParameter.
    result = 0 ifTrue: [ self osError ].
    count := pcReturned value.
    movingPointer := pBuffer.
    printers := OrderedCollection new.
    0 to: count - 1 do: [ :i |
        KernelLibrary
            rtlMoveMemory: printerInfo
            buffer: movingPointer
            length: self printerInfoLength.
        movingPointer := movingPointer + self printerInfoLength.
        pointer := printerInfo addressAtOffset: 0.
        printers add: (String fromAddress: pointer)
    ].
    KernelLibrary localFree: hMem.
    ^printers

"
  Printer enumPrinters: 0
"! !



! Printer class methods !

printerNames
"Answer a collection of all known printer names."
"use getPrinterNames which uses Winspool.dll EnumPrintersA"
    ^self getPrinterNames! !

***           this signature added by listserv             ***
*** Visit  http://www.listserv.dfn.de/archives/vswe-l.html ***
*** for archive browsing and VSWE-L membership management  ***

***           this signature added by listserv             ***
*** Visit  http://www.listserv.dfn.de/archives/vswe-l.html ***
*** for archive browsing and VSWE-L membership management  ***