ネタ元: これでいいの?PRINTER_INFO_2 構造体
興味があったのでちょっと解析してみる。
PRINTER_INFO_2 構造体はちと面倒なんで、PRINTER_INFO_4 構造体を利用し、さくっと test code を書いてみる。
#include "stdafx.h"
#include <windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwNeeded = 0;
DWORD dwReturned = 0;
BOOL bFlag = EnumPrinters(PRINTER_ENUM_LOCAL
, NULL
, 4
, NULL
, 0
, &dwNeeded
, &dwReturned);
if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|| (dwNeeded == 0))
{
return 1;
}
else
{
_tprintf_s(_T("dwNeeded:\t%d\n"), dwNeeded);
SetLastError(0);
}
PPRINTER_INFO_4 ppi4
= (PPRINTER_INFO_4)HeapAlloc(GetProcessHeap()
, HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY
, dwNeeded);
if (ppi4 != NULL)
{
return 1;
}
bFlag = EnumPrinters(PRINTER_ENUM_LOCAL
, NULL
, 4
, (LPBYTE)ppi4
, dwNeeded
, &dwNeeded
, &dwReturned);
if (bFlag == TRUE)
{
for (int i = 0; i < dwReturned; i++)
{
_tprintf_s(_T("%s\n"), ppi4->pPrinterName);
ppi4++;
}
}
if (ppi4 != NULL)
{
HeapFree(GetProcessHeap()
, 0
, ppi4);
return 0;
}
}
で、Sample data というか、printer にこんなのを用意する
| No. |
Printer name |
| 1 |
Microsoft XPS Document Writer |
| 2 |
Microsoft Office Document Image Writer |
| 3 |
FAX |
で、結果はどうなるのかというと、当然こんなのを返す。
dwNeeded: 184
Microsoft XPS Document Writer
Microsoft Office Document Image Writer
FAX
でもそんなのはどうでもよくて、重要なのは内部構造。
解析してみたところこんな感じになっている。
| Address |
Size |
Value |
Description |
| 0x00154ac8 |
4 |
0x00154b44 |
Printer#1 printer name's pointer |
| 0x00154acc |
4 |
0x00000000 |
Printer#1 server name's pointer |
| 0x00154ad0 |
4 |
64 |
Printer#1 Attributes |
| 0x00154ad4 |
4 |
0x00154af6 |
Printer#2 printer name's pointer |
| 0x00154ad8 |
4 |
0x00000000 |
Printer#2 server name's pointer |
| 0x00154adc |
4 |
64 |
Printer#2 Attributes |
| 0x00154ae0 |
4 |
0x00154aee |
Printer#3 printer name's pointer |
| 0x00154ae4 |
4 |
0x00000000 |
Printer#3 server name's pointer |
| 0x00154ae8 |
4 |
64 |
Printer#3 Attributes |
| 0x00154aec |
2 |
0x0000 |
NULL |
| 0x00154aee |
8 |
FAX |
Printer#3 printer name |
| 0x00154af6 |
78 |
Microsoft Office Document Image Writer |
Printer#2 printer name |
| 0x00154b44 |
60 |
Microsoft XPS Document Writer |
Printer#1 printer name |
PRINTER_INFO_4 構造体の大きさは
sizeof(PRINTER_INFO_4) = sizeof(LPTSTR) + sizeof(LPTSTR) + sizeof(DWORD) = 12
この場合の EnumPrinters は PRINTER_INFO_4 構造体の配列を返し、また要素数は 3なので
sizeof(PRINTER_INFO_4) * 3 + 2(配列の NULL終端) = 38
が必要になります。
それから、PRINTER_INFO_4 構造体の中身 pPrinterName の部分もありますから、その分の文字数を count して
(29 + 1) * 2 + (38 + 1) * 2 + (3 + 1) * 2 = 146
両方足して
38 + 146 = 184 = dwNeeded
ということで動的に確保した size にぴったりです。
ということで、ppi4 を HeapFree してやれば全部開放されます。