Skip to content

Commit

Permalink
feat(win32-api): winspool.EnumPrintersW(), winspoolEnumPrinters()
Browse files Browse the repository at this point in the history
  • Loading branch information
waitingsong committed Jul 22, 2022
1 parent 256e7a9 commit e7c1e01
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 36 deletions.
1 change: 1 addition & 0 deletions packages/win32-api/src/func/func.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

export * from './user32/index.user32.js'
export * from './winspool/index.winspool.js'
export * from './winspool/winspool.types.js'

42 changes: 42 additions & 0 deletions packages/win32-api/src/func/winspool/index.winspool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ref,
retriveStruct_PRINTER_INFO,
} from './helper.js'
import { EnumPrintersOptions } from './winspool.types.js'


export async function winspoolClosePrinter(hPrinter: M.HANDLE): Promise<boolean> {
Expand All @@ -24,6 +25,47 @@ export async function winspoolClosePrinter(hPrinter: M.HANDLE): Promise<boolean>
}


/**
* Enumerates available printers, print servers, domains, or print providers.
* @docs https://docs.microsoft.com/en-us/windows/win32/printdocs/enumprinters
*/
export async function winspoolEnumPrinters<Level extends M.EnumPrinters_Level>(
options: EnumPrintersOptions<Level>,
): Promise<M.PRINTER_INFO_X[Level][]> {

const mod = getMod<Win32Fns>(dllName)

const name = ucsBufferFrom(options.Name)
const level = options.Level
assert(level >= 1 && level <= 5, 'level must be >= 1 and <= 5')

const cbBuf = options.cbBuf ?? 4096
assert(cbBuf > 2, 'cbBuf must be > 2')
const pPrinterEnum = Buffer.alloc(cbBuf)

const pcbNeeded = ref.alloc('uint32')
const pcReturned = ref.alloc('uint32')

const ret = await mod.EnumPrintersW(
options.Flags,
name,
level,
pPrinterEnum,
cbBuf,
pcbNeeded,
pcReturned,
)

const count = pcReturned.readUInt32LE()

if (ret && count) {
const arr = retriveStruct_PRINTER_INFO(pPrinterEnum, level, count)
return arr as unknown as Promise<M.PRINTER_INFO_X[Level][]>
}
return []
}


/**
* Retrieves the printer name of the default printer for the current user on the local computer.
* @docs https://docs.microsoft.com/en-us/windows/win32/printdocs/getdefaultprinter
Expand Down
18 changes: 18 additions & 0 deletions packages/win32-api/src/func/winspool/winspool.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { M } from './helper.js'


export interface EnumPrintersOptions<Lvl extends M.EnumPrinters_Level> {
/**
* PrinterEnumFlags
* @see https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-enum-flags
*/
Flags: number
Name?: string
// Level: M.EnumPrinters_Level
Level: Lvl
/**
* @default 4096
*/
cbBuf?: number
}

16 changes: 16 additions & 0 deletions packages/win32-api/src/lib/winspool/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@ export interface Win32Fns {
*/
ClosePrinter: (hPrinter: M.HANDLE) => M.BOOL

/**
* Enumerates available printers, print servers, domains, or print providers.
* @docs https://docs.microsoft.com/en-us/windows/win32/printdocs/enumprinters
*/
EnumPrintersW: (
Flags: M.DWORD,
Name: M.LPTSTR,
Level: M.DWORD,
pPrinterEnum: M.LPBYTE,
cbBuf: M.DWORD,
pcbNeeded: M.LPDWORD,
pcReturned: M.LPDWORD,
) => M.BOOL

/**
* @docs https://docs.microsoft.com/en-us/windows/win32/printdocs/getdefaultprinter
*/
Expand Down Expand Up @@ -49,6 +63,8 @@ export const apiDef: M.DllFuncs<Win32Fns> = {

ClosePrinter: [W.BOOL, [W.HANDLE] ],

EnumPrintersW: [W.BOOL, [W.DWORD, W.LPTSTR, W.DWORD, W.LPBYTE, W.DWORD, W.LPDWORD, W.LPDWORD] ],

GetDefaultPrinterW: [W.BOOL, [W.LPTSTR, W.LPDWORD] ],

GetPrinterW: [W.BOOL, [W.HANDLE, W.DWORD, W.LPBYTE, W.DWORD, W.LPDWORD] ],
Expand Down
6 changes: 6 additions & 0 deletions packages/win32-api/test/config.unittest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ export const calcLpszClassNotepadEdit = Buffer.from('Edit\0', 'ucs2')
export const calcLpszNotepad = 'Notepad'
export const calcLpszNotepadEdit = 'Edit'

/** GitHub CI */
export const githubPrinterNames = [
'Microsoft Print to PDF',
'Microsoft XPS Document Writer',
]

Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
import assert from 'node:assert/strict'

import { fileShortPath } from '@waiting/shared-core'
import ref from 'ref-napi'
import { sleep } from 'zx'

import * as CS from '../../src/index.consts.js'
import { winspoolGetDefaultPrinter } from '../../src/index.fun.js'
import {
DModel as M,
DTypes as W,
DStruct as DS,
StructFactory,
} from '../../src/index.js'
import { CI } from '../root.config.js'


Expand Down
9 changes: 0 additions & 9 deletions packages/win32-api/test/winspool/502.OpenPrinter.test.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import assert from 'node:assert/strict'

import { fileShortPath } from '@waiting/shared-core'
import ref from 'ref-napi'
import { sleep } from 'zx'

import * as CS from '../../src/index.consts.js'
import {
winspoolGetDefaultPrinter,
winspoolOpenPrinter,
} from '../../src/index.fun.js'
import {
DModel as M,
DTypes as W,
DStruct as DS,
StructFactory,
} from '../../src/index.js'


describe(fileShortPath(import.meta.url), () => {
Expand Down
9 changes: 0 additions & 9 deletions packages/win32-api/test/winspool/503.GetPrinter.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import assert from 'node:assert/strict'

import { fileShortPath } from '@waiting/shared-core'
import ref from 'ref-napi'
import { sleep } from 'zx'

import * as CS from '../../src/index.consts.js'
import {
winspoolGetDefaultPrinter,
winspoolGetPrinter,
winspoolOpenPrinter,
} from '../../src/index.fun.js'
import {
DModel as M,
DTypes as W,
DStruct as DS,
StructFactory,
} from '../../src/index.js'
import { CI } from '../root.config.js'


Expand Down
9 changes: 0 additions & 9 deletions packages/win32-api/test/winspool/504.ClosePrinter.test.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
import assert from 'node:assert/strict'

import { fileShortPath } from '@waiting/shared-core'
import ref from 'ref-napi'
import { sleep } from 'zx'

import * as CS from '../../src/index.consts.js'
import {
winspoolClosePrinter,
winspoolGetDefaultPrinter,
winspoolGetPrinter,
winspoolOpenPrinter,
} from '../../src/index.fun.js'
import {
DModel as M,
DTypes as W,
DStruct as DS,
StructFactory,
} from '../../src/index.js'
import { CI } from '../root.config.js'


Expand Down
72 changes: 72 additions & 0 deletions packages/win32-api/test/winspool/505.EnumPrinters.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import assert from 'node:assert/strict'

import { fileShortPath } from '@waiting/shared-core'
import { PrinterEnumFlags } from 'win32-def/consts'

import {
winspoolOpenPrinter,
winspoolEnumPrinters,
EnumPrintersOptions,
} from '../../src/index.fun.js'
import {
DModel as M,
DTypes as W,
DStruct as DS,
StructFactory,
} from '../../src/index.js'
import { githubPrinterNames } from '../config.unittest.js'
import { CI } from '../root.config.js'


describe(fileShortPath(import.meta.url), () => {

describe('Should winspoolEnumPrinters() work', () => {
it('normal', async () => {
const ret = await winspoolEnumPrinters({
Flags: PrinterEnumFlags.PRINTER_ENUM_LOCAL,
Level: 4,
})
assertsPInfo(ret, true)
})

it('options<4>', async () => {
const opts: EnumPrintersOptions<4> = {
Flags: PrinterEnumFlags.PRINTER_ENUM_LOCAL,
Level: 4,
}
const ret = await winspoolEnumPrinters(opts)
assertsPInfo(ret, false)
})

it('options as const', async () => {
const opts = {
Flags: PrinterEnumFlags.PRINTER_ENUM_LOCAL,
Level: 4,
} as const // <-- `as const`
const ret = await winspoolEnumPrinters(opts)
assertsPInfo(ret, false)
})

})
})


function assertsPInfo(infos: M.PRINTER_INFO_X[4][], verbose: boolean): void {
assert(infos.length)

infos.forEach((info, idx) => {
assert(info)
const { pPrinterName, pServerName, Attributes } = info
assert(info.pPrinterName)
verbose && console.log({
idx,
pPrinterName,
pServerName,
Attributes,
})
if (CI) {
githubPrinterNames.includes(pPrinterName)
}
})
}

0 comments on commit e7c1e01

Please sign in to comment.