Pourquoi EnumPrintersA et EnumPrintersW demande la même quantité de mémoire?

J'appelle EnumPrintersA/EnumPrintersW fonctions à l'aide de nœud-ffi pour obtenir la liste des imprimantes locales accessible à partir de mon PC.

Vous devez créer le tampon qui sera rempli avec des informations par EnumPrinters fonction.

Mais vous ne connaissez pas la taille de la mémoire tampon.

Dans ce cas, vous devez exécuter EnumPrintersA/EnumPrintersW deux fois.

Lors du premier appel de cette fonction calcule la quantité de mémoire pour plus d'informations sur les imprimantes, au cours de la deuxième appel de cette fonction remplit le tampon avec des informations sur les imprimantes.

Dans le cas de la version Unicode de EnumPrinters de la fonction, chaque lettre dans les imprimantes nom sera codé à l'aide de deux caractères dans Windows.

Pourquoi le premier appel à EnumPrintersW renvoie la même quantité de mémoire que le premier appel à EnumPrintersA?

Des chaînes Unicode sont deux fois plus longtemps que les non-unicode, mais la taille de mémoire tampon requise est la même.

var ffi = require('ffi')
var ref = require('ref')
var Struct = require('ref-struct')
var wchar_t = require('ref-wchar')
var int = ref.types.int
var intPtr = ref.refType(ref.types.int)
var wchar_string = wchar_t.string
var getPrintersA =  function getPrinters() {
var PRINTER_INFO_4A = Struct({
'pPrinterName' : ref.types.CString,
'pServerName' : ref.types.CString,
'Attributes' : int
});
var printerInfoPtr = ref.refType(PRINTER_INFO_4A);
var winspoolLib = new ffi.Library('winspool', {
'EnumPrintersA': [ int, [ int, ref.types.CString, int, printerInfoPtr, int, intPtr, intPtr ] ]
});
var pcbNeeded = ref.alloc(int, 0);
var pcReturned = ref.alloc(int, 0);
//Get amount of memory for the buffer with information about printers
var res = winspoolLib.EnumPrintersA(6, ref.NULL, 4, ref.NULL, 0, pcbNeeded, pcReturned);
if (res != 0) {
console.log("Cannot get list of printers. Error during first call to EnumPrintersA. Error: " + res);
return;
}
var bufSize = pcbNeeded.deref();
var buf = Buffer.alloc(bufSize);
console.log(bufSize);
//Fill buf with information about printers
res = winspoolLib.EnumPrintersA(6, ref.NULL, 4, buf, bufSize, pcbNeeded, pcReturned);
if (res == 0) {
console.log("Cannot get list of printers. Eror: " + res);
return;
}
var countOfPrinters = pcReturned.deref();
var printers = Array(countOfPrinters);
for (var i = 0; i < countOfPrinters; i++) {
var pPrinterInfo = ref.get(buf, i*PRINTER_INFO_4A.size, PRINTER_INFO_4A);
printers[i] = pPrinterInfo.pPrinterName;
}
return printers;
};
var getPrintersW =  function getPrinters() {
var PRINTER_INFO_4W = Struct({
'pPrinterName' : wchar_string,
'pServerName' : wchar_string,
'Attributes' : int
});
var printerInfoPtr = ref.refType(PRINTER_INFO_4W);
var winspoolLib = new ffi.Library('winspool', {
'EnumPrintersW': [ int, [ int, wchar_string, int, printerInfoPtr, int, intPtr, intPtr ] ]
});
var pcbNeeded = ref.alloc(int, 0);
var pcReturned = ref.alloc(int, 0);
//Get amount of memory for the buffer with information about printers
var res = winspoolLib.EnumPrintersW(6, ref.NULL, 4, ref.NULL, 0, pcbNeeded, pcReturned);
if (res != 0) {
console.log("Cannot get list of printers. Error during first call to EnumPrintersW. Eror code: " + res);
return;
}
var bufSize = pcbNeeded.deref();
var buf = Buffer.alloc(bufSize);
console.log(bufSize);
//Fill buf with information about printers
res = winspoolLib.EnumPrintersW(6, ref.NULL, 4, buf, pcbNeeded.deref(), pcbNeeded, pcReturned);
if (res == 0) {
console.log("Cannot get list of printers. Eror code: " + res);
return;
}
var countOfPrinters = pcReturned.deref();
var printers = new Array(countOfPrinters);
for (var i = 0; i < countOfPrinters; i++) {
var pPrinterInfo = ref.get(buf, i*PRINTER_INFO_4W.size, PRINTER_INFO_4W);
printers[i] = pPrinterInfo.pPrinterName;
}
return printers;
};

https://msdn.microsoft.com/ru-ru/library/windows/desktop/dd162692(v=vs. 85).aspx

BOOL EnumPrinters(
_In_  DWORD   Flags,
_In_  LPTSTR  Name,
_In_  DWORD   Level,
_Out_ LPBYTE  pPrinterEnum,
_In_  DWORD   cbBuf,
_Out_ LPDWORD pcbNeeded,
_Out_ LPDWORD pcReturned
);

https://msdn.microsoft.com/ru-ru/library/windows/desktop/dd162847(v=vs. 85).aspx

typedef struct _PRINTER_INFO_4 {
LPTSTR pPrinterName;
LPTSTR pServerName;
DWORD  Attributes;
} PRINTER_INFO_4, *PPRINTER_INFO_4;

OriginalL'auteur Volodymyr Bezuglyy | 2016-12-14