• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

所謂テキストファイルを印刷するツールです。emacsと連携しやすくなっています。


Commit MetaInfo

Révisionaddca1cffa243e4bc1d4d5504d10f9eaa93a3f9a (tree)
l'heure2005-05-08 22:00:47
Auteurtfuruka1 <tfuruka1>
Commitertfuruka1

Message de Log

作業ファイル作成関数を追加しました。従来のファイルポインタを返却する方
法だと、DLLにした時にアクセスバイオレーションが発生するので、ファイル
名のみを返却する関数を追加しました。

Change Summary

Modification

--- a/src/dllmain.c
+++ b/src/dllmain.c
@@ -1,785 +1,811 @@
1-/* -*- mode: C++; coding: sjis-dos; -*-
2- * Time-stamp: <2004-12-23 19:47:54 tfuruka1>
3- * $Id: dllmain.c,v 1.20 2004/12/23 13:14:24 tfuruka1 Exp $
4- *
5- * ak2ps のようなものの共通 DLL
6- *
1+/* -*- mode: C++; coding: sjis; -*-
2+ * Time-stamp: <2005-05-08 21:59:26 tfuruka1>
3+ * $Id: dllmain.c,v 1.21 2005/05/08 13:00:47 tfuruka1 Exp $
4+ *
5+ * ak2ps のようなものの共通 DLL
6+ *
77 * $Log: dllmain.c,v $
8+ * Revision 1.21 2005/05/08 13:00:47 tfuruka1
9+ * 作業ファイル作成関数を追加しました。従来のファイルポインタを返却する方
10+ * 法だと、DLLにした時にアクセスバイオレーションが発生するので、ファイル
11+ * 名のみを返却する関数を追加しました。
12+ *
813 * Revision 1.20 2004/12/23 13:14:24 tfuruka1
914 * 折り返し動作をコマンド引数に追加した事と、それに共なう修正。
10- *
11- * Revision 1.19 2004/06/18 00:57:57 tfuruka1
12- * 改行コードの修正のみです。
13- *
14- * Revision 1.18 2004/01/12 09:58:24 tfuruka1
15- * 長辺綴じと短辺綴じに対応しました。
16- *
17- * Revision 1.17 2004/01/11 11:48:06 tfuruka1
18- * 作業ファイルの作成ルーチンにSyslogを追加しました。
19- *
20- * Revision 1.16 2004/01/11 10:52:37 tfuruka1
21- * バッファ名にリダイレクト記号 (aaa<3>等)が含まれていると作業ファイル
22- * の作成に失敗していた問題を修正しました。
23- *
24- * Revision 1.15 2003/04/11 21:40:44 tfuruka1
25- * GetLongBaseName関数で自動変数のポインタを返却していたバグを修正(露見
26- * していなかったが、メモリ破壊をおこす可能性あり)
27- *
28- * Revision 1.14 2003/03/29 12:43:59 tfuruka1
29- * ● SendPrintFromStdin関数でクリップボードの内容を読み込む処理を追加し
30- * た。
31- *
32- * Revision 1.13 2003/03/14 15:06:19 tfuruka1
33- * ● Syslog関数の仕様変更に伴い、Syslog関数を使用している部分の修正を行っ
34- * た。
35- * ● 作業ファイルの作成ルールを一部変更した(.を_に変更)。Distillerが作成
36- * するPDFファイルが、拡張子以降を無視するので、出力ファイル名が重複す
37- * るのを避けるのが目的である。
38- * ● サーバの起動関数に、サーバの起動オプションを追加した。
39- * ● Syslog関数の仕様を変更した。第一パラメータに標準出力オプションを追
40- * 加した。
41- * ● PostScriptファイルからタイトルを取得する関数を追加した。
42- *
43- * Revision 1.12 2003/03/01 09:01:25 tfuruka1
44- * ● 作業ファイルの作成処理において、ファイル名に使用出来ない文字が指定去
45- * れた場合に適切な文字に変更するように修正を行った。
46- *
47- * Revision 1.11 2003/02/25 15:28:35 tfuruka1
48- * 行番号印刷の処理追加による対応を行った。
49- *
50- * Revision 1.10 2001/12/23 10:23:33 tfuruka1
51- * ●作業ディレクトリ名取得の関数を新規追加(作業ファイル作成関数から切り出
52- * し)
53- *
54- * Revision 1.9 2001/12/17 14:33:17 tfuruka1
55- * syslog内部で標準出力へ出力していた処理を削除した(やっぱりうっとうしい
56- * ので)。
57- *
58- * Revision 1.8 2001/12/14 17:04:43 tfuruka1
59- * プレビュー対応
60- *
61- * Revision 1.7 2001/12/08 15:19:06 tfuruka1
62- * 用紙サイズの指定対応の対応漏れの対応。
63- *
64- * Revision 1.6 2001/12/07 18:25:11 tfuruka1
65- * 用紙サイズの指定を出来るようにした。
66- *
67- * Revision 1.5 2001/10/01 13:20:47 tfuruka1
68- * 用紙の向きを指定出来るように修正。
69- *
70- * Revision 1.4 2001/08/19 04:35:57 tfuruka1
71- * PostScriptファイルの暫定対応(ただ単にDistillerの監視フォルダに放り込
72- * むだけ)。
73- *
74- * Revision 1.3 2001/08/18 16:30:30 tfuruka1
75- * ●作業ファイルの作成に_mktemp関数を使用していたが、よく考えたらこの関
76- * 数は、最大で 27 個しか一意なファイル名を作成できない事に気が付いた
77- * (というか、エラーが出た)ので、_mktempのbaseが極力一意になるように
78- * して、27個以上の一意なファイルを作成できるようにした。
79- * ●MessageBoxを使用している部分をSyslogを使用するように変更した(Meadow
80- * から呼ばれた時にMessageBoxを使用すると、Windowが見えないのでダイアロ
81- * グを閉じる事ができなくなるので)。
82- * ●SendPrintFromFile関数を廃止し、SendPrintFromFileCopy関数に統合した。
83- * ●Syslog関数で、標準出力にも出力するようにした(syslogdがなくてもデ
84- * バッグできる)。
85- *
86- * Revision 1.2 2001/02/05 17:38:02 tfuruka1
87- * RCSがおかしくなったので、復旧した。過去の修正内容は以下の通り。
88- * ●標準入力から読み込んだバイト数がゼロの場合は処理を行わないように修正
89- * した。
90- * ●Syslog関数を追加した。主な目的はデバッグ用である。
91- * ●GetLongBaseName関数を追加した。
92- *
93- * Revision 1.1 2001/02/05 17:35:32 tfuruka1
94- * Initial revision
95- *
96- *
97- */
98-// (replace-regexp "[ \t]+$" "")
99-#include "ak2prs.h"
100-#include "ak2pr.h"
101-
102-/* 用紙サイズの一覧 */
103-static struct {
104- LPTSTR cmdOpt; // コマンドパラメータ等
105- short dmPaperSize; // DEVMODEのパラメータ
106- LPTSTR sComment; // 用紙の説明
107-} devModePs[] = {
108- {"A3", DMPAPER_A3, "A3シート, 297×420ミリメートル"},
109- {"A4", DMPAPER_A4, "A4シート, 210×297ミリメートル"},
110- {"A4SMALL", DMPAPER_A4SMALL, "A4 small シート, 210×297ミリメートル"},
111- {"A5", DMPAPER_A5, "A5シート, 148×210ミリメートル"},
112- {"B4", DMPAPER_B4, "B4シート, 250×354ミリメートル"},
113- {"B5", DMPAPER_B5, "B5シート, 182×257ミリメートル"},
114- {"LETTER", DMPAPER_LETTER, "Letter, 8 1/2×11インチ"},
115- {"LEGAL", DMPAPER_LEGAL, "Legal, 8 1/2×14インチ"},
116- {"CSHEET", DMPAPER_CSHEET, "C シート, 17×22インチ"},
117- {"DSHEET", DMPAPER_DSHEET, "D シート, 22×34インチ"},
118- {"ESHEET", DMPAPER_ESHEET, "E シート, 34×44インチ"},
119- {"LETTERSMALL", DMPAPER_LETTERSMALL, "Letter Small, 8 1/2×11インチ"},
120- {"TABLOID", DMPAPER_TABLOID, "Tabloid, 11×17インチ"},
121- {"LEDGER", DMPAPER_LEDGER, "Ledger, 17×11インチ"},
122- {"STATEMENT", DMPAPER_STATEMENT, "Statement, 5 1/2×8 1/2インチ"},
123- {"EXECUTIVE", DMPAPER_EXECUTIVE, "Executive, 7 1/4×10 1/2インチ"},
124- {"FOLIO", DMPAPER_FOLIO, "Folio, 8 1/2×13インチ"},
125- {"QUARTO", DMPAPER_QUARTO, "Quarto, 215×275ミリメートル"},
126- {"10X14", DMPAPER_10X14, "10×14インチシート"},
127- {"11X17", DMPAPER_11X17, "11×17インチシート"},
128- {"NOTE", DMPAPER_NOTE, "Note, 8 1/2×11インチ"},
129- {"ENV_9", DMPAPER_ENV_9, "#9 Envelope, 3 7/8×8 7/8インチ"},
130- {"ENV_10", DMPAPER_ENV_10, "#10 Envelope, 4 1/8×9 1/2インチ"},
131- {"ENV_11", DMPAPER_ENV_11, "#11 Envelope, 4 1/2×10 3/8インチ"},
132- {"ENV_12", DMPAPER_ENV_12, "#12 Envelope, 4 3/4×11インチ"},
133- {"ENV_14", DMPAPER_ENV_14, "#14 Envelope, 5×11 1/2インチ"},
134- {"ENV_DL", DMPAPER_ENV_DL, "DL Envelope, 110×220ミリメートル"},
135- {"ENV_C5", DMPAPER_ENV_C5, "C5 Envelope, 162×229ミリメートル"},
136- {"ENV_C3", DMPAPER_ENV_C3, "C3 Envelope, 324×458ミリメートル"},
137- {"ENV_C4", DMPAPER_ENV_C4, "C4 Envelope, 229×324ミリメートル"},
138- {"ENV_C6", DMPAPER_ENV_C6, "C6 Envelope, 114×162ミリメートル"},
139- {"ENV_C65", DMPAPER_ENV_C65, "C65 Envelope, 114×229ミリメートル"},
140- {"ENV_B4", DMPAPER_ENV_B4, "B4 Envelope, 250×353ミリメートル"},
141- {"ENV_B5", DMPAPER_ENV_B5, "B5 Envelope, 176×250ミリメートル"},
142- {"ENV_B6", DMPAPER_ENV_B6, "B6 Envelope, 176×125ミリメートル"},
143- {"ENV_ITALY", DMPAPER_ENV_ITALY, "Italy Envelope, 110×230ミリメートル"},
144- {"ENV_MONARCH", DMPAPER_ENV_MONARCH,
145- "Monarch Envelope, 3 7/8×7 1/2インチ"},
146- {"ENV_PERSONAL", DMPAPER_ENV_PERSONAL,
147- "6 3/4 Envelope, 3 5/8×6 1/2インチ"},
148- {"FANFOLD_US", DMPAPER_FANFOLD_US, "US Std Fanfold, 14 7/8×11インチ"},
149- {"FANFOLD_STD_GERMAN", DMPAPER_FANFOLD_STD_GERMAN,
150- "German Std Fanfold, 8 1/2×12インチ"},
151- {"FANFOLD_LGL_GERMAN", DMPAPER_FANFOLD_LGL_GERMAN,
152- "German Legal Fanfold, 8 1/2×13インチ"},
153- {NULL, 0, NULL}
154-};
155-
156-/*--------------------------------------------------------------------
157- * dwErr で指定されたエラーコードに対応するエラーメッセージを関数にシ
158- * ステムメッセージテーブルリソースから検索して一時的な文字列へのポイ
159- * ンタを返却する。dwErr は GetLastError から得た値を指定する事。lpsz
160- * はエラーメッセージへ追加する文字列を指定する。API 名等を指定する。
161- * *-------------------------------------------------------------------*/
162-LPCSTR WINAPI
163-GetLastErrorMessage(LPCSTR lpsz, DWORD dwErr)
164-{
165-#ifdef _WIN32_WCE
166- static LPTSTR sz = "WindowsCE では GetLastErrorMessage はみサポートです";
167- return sz;
168-#else
169- static char sz[1024];
170- char szTmp[256];
171- int i;
172-
173- if (!(i = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
174- FORMAT_MESSAGE_IGNORE_INSERTS,
175- NULL, dwErr, 0, szTmp, sizeof(szTmp), NULL))) {
176- strcpy(szTmp, "---");
177- }
178- else {
179- szTmp[i] = '\0';
180- for (i--; 0 <= i; i--) {
181- if ('\n' == szTmp[i] || '\r' == szTmp[i]) {
182- szTmp[i] = '\0';
183- }
184- }
185- }
186- wsprintf(sz, "[WIN32] %s: Error Code = %d(%#02x): %s",
187- lpsz, dwErr, dwErr, szTmp);
188- return (LPCTSTR)sz;
189-#endif
190-}
191-
192-/*--------------------------------------------------------------------
193- * 作業用ディレクトリ名を得る。作業ディレクトリ名は書き換えてはいけま
194- * せん。
195- * *-------------------------------------------------------------------*/
196-LPCTSTR WINAPI
197-GetTempDirectoryName()
198-{
199- static TCHAR szTempDirName[MAX_PATH] = "\0";
200- char *p1;
201- DWORD dwFA;
202- int i;
203-
204- if (NULL == (p1 = getenv("TEMP"))) {
205- Syslog(TRUE, "%s#%d: 環境変数TEMPが見つかりません",
206- __FILE__, __LINE__);
207- return NULL;
208- }
209-
210- for (i = 0; i < 100; i++) {
211- sprintf(szTempDirName, "%s\\ak2prTempDir%d", p1, i);
212- if (0xFFFFFFFF == (dwFA = GetFileAttributes(szTempDirName))) {
213- if (0 != _mkdir(szTempDirName)) {
214- continue;
215- }
216- break;
217- }
218- if (dwFA & FILE_ATTRIBUTE_DIRECTORY) {
219- break;
220- }
221- }
222- if (100 <= i) {
223- Syslog(TRUE, "%s#%d: 作業ディレクトリが作成できません",
224- __FILE__, __LINE__);
225- szTempDirName[0] ='\0';
226- return NULL;
227- }
228- return (LPCTSTR)szTempDirName;
229-}
230-
231-/*--------------------------------------------------------------------
232- * 作業ファイルを作成する。正常に作成出来た場合はファイルポインタを返
233- * 却する。作成できなかった場合は NULL を返却する。mode は fopen の
234- * mode と全く同じである。また, ファイルを使用し終った後は fclose でファ
235- * イルをクローズ後, lpszFileName で返却したファイルを削除しなければな
236- * らない。
237- * *-------------------------------------------------------------------*/
238-FILE * WINAPI
239-MakeTempFile(
240- IN const char *mode, // モード
241- IN OUT LPTSTR lpszFileName // 作成した作業ファイル名
242- )
243-{
244- static int iCnt = 0;
245- FILE *fp;
246- time_t t;
247- TCHAR szFileName[MAX_PATH];
248- LPCTSTR lpszDir;
249- int i;
250-
251- // ファイル名に * や \ 等が含まれていると、正しいファイルを作成で
252- // きないので、適切な文字に置き換える
253- Syslog(FALSE, "MakeTempFile Request filename: %s", lpszFileName);
254- for (i = 0; *(lpszFileName + i); i++) {
255- // 漢字の一バイト目の場合は次の文字もスキップする
256- if (IsKanjiSJIS(*((LPBYTE)lpszFileName + i))) {
257- i++;
258- continue;
259- }
260- switch (*(lpszFileName + i)) {
261- case '*':
262- case '?':
263- case '/':
264- case ':':
265- case '\\':
266- case '<':
267- case '>':
268- *(lpszFileName + i) = '#';
269- break;
270- case ' ':
271- *(lpszFileName + i) = '-';
272- break;
273- case '.': // Distillerが拡張子と
274- // 判断するので
275- *(lpszFileName + i) = '_';
276- break;
277- }
278- }
279-
280- if (!(lpszDir = GetTempDirectoryName())) {
281- return NULL;
282- }
283-
284- iCnt++;
285- iCnt %= 256;
286-
287- t = time(NULL);
288-
289- strncpy(szFileName, lpszFileName, MAX_PATH);
290- sprintf(lpszFileName, "%s\\%s~%08x_%d_XXXXXX",
291- lpszDir, szFileName, t, iCnt);
292- Syslog(FALSE, "MakeTempFile Response filename: %s", lpszFileName);
293- if (!_mktemp(lpszFileName)) {
294- Syslog(TRUE, "%s#%d: 作業ファイルが作成できません",
295- __FILE__, __LINE__);
296- return NULL;
297- }
298- if (NULL == (fp = fopen(lpszFileName, mode))) {
299- Syslog(TRUE, "%s#%d: 作業ファイル[%s]をオープンできません(%s)",
300- __FILE__, __LINE__, lpszFileName, strerror(0));
301- return NULL;
302- }
303- return fp;
304-}
305-
306-/*--------------------------------------------------------------------
307- * 自分自身が格納されているディレクトリ名への一時的なポインタを得る。
308- * 返却するポインタは一時的なものなので, 必要な場合は複写して使用する
309- * 事。
310- * *-------------------------------------------------------------------*/
311-LPCTSTR WINAPI
312-GetMyDir(VOID)
313-{
314- static TCHAR szBuf[1024];
315- char *p1, *p2;
316-
317- // ファイルのフルパスを得る
318- if (!GetModuleFileName(GetModuleHandle(NULL), szBuf, 1024)) {
319- int nErr = GetLastError();
320- Syslog(TRUE, "%s#%d: %s", __FILE__, __LINE__,
321- GetLastErrorMessage("GetModuleHandle", nErr));
322- return NULL;
323- }
324-
325- p1 = strrchr(szBuf, '\\');
326- p2 = strrchr(szBuf, '/');
327- p1 = ((ULONG)p1 > (ULONG)p2) ? p1 : p2;
328- if (!p1) {
329- strcpy(szBuf, "./");
330- }
331- else {
332- *(p1 + 1) = '\0';
333- }
334- return (LPCTSTR)szBuf;
335-}
336-
337-/*--------------------------------------------------------------------
338- * Unixのbasenameと同じ。返却するポインタは一時的なポインタなので、必
339- * ずコピーして使用する必要がある。
340- * *-------------------------------------------------------------------*/
341-LPCTSTR WINAPI
342-BaseName(LPCTSTR lpszPath)
343-{
344- LPCTSTR a, b;
345-
346- a = _mbsrchr(lpszPath, '\\');
347- b = _mbsrchr(lpszPath, '/');
348-
349- if (a == b) { // 等しい時は NULLしかない
350- return lpszPath;
351- }
352-
353- return ((ULONG)a > (ULONG)b ? a : b) + 1;
354-}
355-LPCTSTR WINAPI
356-GetLongBaseName(LPCTSTR lpszPath)
357-{
358- HANDLE hFile;
359- static WIN32_FIND_DATA wfd;
360-
361- hFile = FindFirstFile(lpszPath, &wfd);
362- if (INVALID_HANDLE_VALUE == hFile) {
363- return BaseName(lpszPath);
364- }
365- FindClose(hFile);
366- return wfd.cFileName;
367-}
368-
369-/*--------------------------------------------------------------------
370- * プリントサーバが起動しているかチェックする。起動していた場合は HWND
371- * を返却する。未起動の場合は NULL を返す。
372- * *-------------------------------------------------------------------*/
373-BOOL WINAPI
374-IsPrtServerEnable(VOID)
375-{
376- return (BOOL)FindWindow(SV_CLASS, SV_CAPTION);
377-}
378-
379-/*--------------------------------------------------------------------
380- * プリントサーバを起動する。正常に起動出来た場合は TRUE を返却する。起
381- * 動できなかった場合は FALSE を返す。
382- * *-------------------------------------------------------------------*/
383-BOOL WINAPI
384-ExecutePrtServer(LPCTSTR lpszOption)
385-{
386- PROCESS_INFORMATION pi; // プロセス情報
387- STARTUPINFO sui; // 起動情報
388- TCHAR szImageName[1024]; // モジュール名
389- LPCTSTR lpszMyDir; // 自分のディレクトリ
390- int i; // 汎用
391-
392- if (IsPrtServerEnable()) // 既に起動していた場合は
393- return TRUE; // 正常に起動したものとする
394-
395- if (!(lpszMyDir = GetMyDir())) { // 自分自身のディレクトリを得る
396- return FALSE;
397- }
398-
399- // 実行ファイルを作成する
400- sprintf(szImageName, "%s/%s %s", lpszMyDir, SV_EXE_NAME, lpszOption);
401-
402- // プロセス情報と起動情報の初期化
403- memset(&sui, 0, sizeof(STARTUPINFO));
404- memset(&pi, 0, sizeof(PROCESS_INFORMATION));
405- sui.cb = sizeof(STARTUPINFO);
406- sui.dwFlags = STARTF_USESHOWWINDOW;
407- sui.wShowWindow = SW_SHOWNORMAL;
408-
409- if (!CreateProcess(NULL, szImageName, NULL, NULL, FALSE,
410- 0, NULL, NULL, &sui, &pi )) {
411- int nErr = GetLastError();
412- Syslog(TRUE, "%s#%d: %s", __FILE__, __LINE__,
413- GetLastErrorMessage("CreateProcess", nErr));
414- return FALSE;
415- }
416-
417- // WaitForInputIdle(pi.hProcess, INFINITE);
418- // ウィンドウが生々されるまで待つ
419- for (i = 0; i < 10; i++) {
420- if (IsPrtServerEnable()) {
421- break;
422- }
423- Sleep(1000);
424- }
425- // プロセスハンドルは必要無いので閉じる
426- CloseHandle(pi.hProcess);
427-
428- if (pi.hThread) { // スレッドハンドルも閉じる
429- CloseHandle(pi.hThread);
430- }
431-
432- // もう一度サーバーをチェックする
433- if (!IsPrtServerEnable()) {
434- Syslog(TRUE, "%s#%d: サーバの起動に失敗したようです",
435- __FILE__, __LINE__);
436- return FALSE;
437- }
438- return TRUE; // 正常起動
439-}
440-
441-/*--------------------------------------------------------------------
442- * プリントサーバへ印刷情報を送信する。
443- * *-------------------------------------------------------------------*/
444-static BOOL WINAPI
445-SendPrintData(
446- HWND hWnd, // 送信元のハンドル
447- PPRT_INFO pPrtInfo // 印刷情報
448- )
449-{
450- HWND hWndTo; // 送信先のハンドル
451- COPYDATASTRUCT cds; // 送信データ
452-
453- if (!ExecutePrtServer(NULL)) { // プリンタサーバを起動
454- return FALSE; // サーバが居ない
455- }
456-
457- // DLLのVarsion不一致を防ぐ為, タイムスタンプを埋める
458- strcpy(pPrtInfo->szTimeStamp, TIMESTAMP);
459- strcpy(pPrtInfo->szTimeStamp1, TIMESTAMP);
460-
461- // サーバのハンドルを得る
462- if (!(hWndTo = FindWindow(SV_CLASS, SV_CAPTION))) {
463- int nErr = GetLastError();
464- Syslog(TRUE, "%s#%d: %s", __FILE__, __LINE__,
465- GetLastErrorMessage("FindWindow", nErr));
466- return FALSE;
467- }
468-
469- // 送信データを設定する
470- cds.dwData = 0;
471- cds.cbData = sizeof(PRT_INFO);
472- cds.lpData = (LPVOID)pPrtInfo;
473-
474- // 印刷情報を送信する
475- return SendMessage(hWndTo, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
476-}
477-
478-/*--------------------------------------------------------------------
479- * 標準入力の内容を読み込みプリントサーバへ印刷情報を送信する。標準入
480- * 力の代わりにクリップボードからテキストを読み込む事も可能である。
481- * *-------------------------------------------------------------------*/
482-BOOL WINAPI
483-SendPrintFromStdin(
484- BOOL bClipBoard, // T:クリップボード
485- HWND hWnd, // ハンドル
486- LPCTSTR lpszTitle, // タイトル未指定時は"stdin"
487- int nNumOfUp, // 段組数
488- int nTab, // タブ幅
489- double fFontSize, // フォントサイズ
490- int nType, // 印刷データタイプ
491- int nOrientation, // 用紙の向き
492- short dmPaperSize, // 用紙サイズ
493- int bNum, // 行番号の印刷
494- int nBinding, // 綴じ方向
495- int nSingleLine // 折り返し動作
496- )
497-{
498- PRT_INFO PrtInfo; // プリントファイル情報
499- FILE *fp; // ファイルポインタ
500- TCHAR szBuf[1024]; // 標準入力用バッファ
501- BOOL bNotZero = FALSE; // ファイルサイズゼロ
502-
503- // プリントファイル情報の初期化
504- memset((LPVOID)&PrtInfo, 0, sizeof(PRT_INFO));
505- if (lpszTitle) {
506- strncpy(PrtInfo.szTitle, lpszTitle, 255);
507- } else {
508- strcpy(PrtInfo.szTitle, bClipBoard ? "Clipboard" : "stdin");
509- }
510-
511- PrtInfo.nNumOfUp = nNumOfUp;
512- PrtInfo.nTab = nTab;
513- PrtInfo.nType = nType;
514- PrtInfo.fFontSize = fFontSize;
515- PrtInfo.nOrientation = nOrientation;
516- PrtInfo.dmPaperSize = dmPaperSize;
517- PrtInfo.bPreView = FALSE;
518- PrtInfo.bNum = bNum; // 行番号の印刷(-1:サーバ)
519- PrtInfo.bShortBinding = nBinding; // 綴じ方向(-1:サーバ)
520- PrtInfo.nSingleLine = nSingleLine; // 折り返し動作
521-
522- // 作業ファイルを作成する
523- strcpy(PrtInfo.szFileName, PrtInfo.szTitle);
524- if (NULL == (fp = MakeTempFile("wt", PrtInfo.szFileName))) {
525- return FALSE;
526- }
527-
528- if (bClipBoard) {
529- // クリップボードからファイルに読み込む
530- bNotZero = ReadClipBoardToFP(NULL, fp);
531- }
532- else {
533- // 標準入力から読み込む
534- while (fgets(szBuf, 1024, stdin)) {
535- fprintf(fp, "%s", szBuf);
536- bNotZero++;
537- }
538- }
539-
540- fclose(fp);
541- if (!bNotZero) {
542- unlink(PrtInfo.szFileName);
543- Syslog(TRUE, "%s", "ファイルサイズが0なのでキャンセルします");
544- return FALSE;
545- }
546-
547- return SendPrintData(hWnd, &PrtInfo);
548-}
549-
550-/*--------------------------------------------------------------------
551- * 指定されたファイルを一時ファイルへ複写し,プリントサーバへ印刷情報
552- * を送信する。
553- * *-------------------------------------------------------------------*/
554-BOOL WINAPI
555-SendPrintFromFileCopy(
556- HWND hWnd, // ハンドル
557- LPCTSTR lpszTitle, // タイトル未指定時は"stdin"
558- LPCTSTR lpszFileName, // コピー元ファイル名
559- int nNumOfUp, // 段組数
560- int nTab, // タブ幅
561- double fFontSize, // フォントサイズ
562- int nType, // 印刷データタイプ
563- int nOrientation, // 用紙の向き
564- short dmPaperSize, // 用紙サイズ
565- int bNum, // 行番号印刷
566- int nBinding, // 綴じ方向
567- int nSingleLine // 折り返し動作
568- )
569-{
570- PRT_INFO PrtInfo; // プリントファイル情報
571- FILE *fp; // ファイルポインタ
572- DWORD dwFA; // ファイル情報
573-
574- // ファイルの存在チェックを行う
575- if (0xFFFFFFFF == (dwFA = GetFileAttributes(lpszFileName))) {
576- LPCTSTR p;
577- dwFA = GetLastError();
578- p = GetLastErrorMessage("GetFileAttributes()", dwFA);
579- Syslog(TRUE, "%s#%d: %s %s", __FILE__, __LINE__, p, lpszFileName);
580- return FALSE;
581- }
582-
583- // ディレクトリの場合はエラー
584- if (dwFA & FILE_ATTRIBUTE_DIRECTORY) {
585- Syslog(TRUE, "%s#%d: %sはディレクトリです",
586- __FILE__, __LINE__, lpszFileName);
587- return FALSE;
588- }
589-
590- // プリントファイル情報の初期化
591- memset((LPVOID)&PrtInfo, 0, sizeof(PRT_INFO));
592- if (lpszTitle) {
593- strncpy(PrtInfo.szTitle, lpszTitle, 255);
594- } else {
595- strncpy(PrtInfo.szTitle, GetLongBaseName(lpszFileName), 255);
596- }
597-
598- PrtInfo.nNumOfUp = nNumOfUp;
599- PrtInfo.nTab = nTab;
600- PrtInfo.nType = nType;
601- PrtInfo.fFontSize = fFontSize;
602- PrtInfo.nOrientation = nOrientation;
603- PrtInfo.dmPaperSize = dmPaperSize;
604- PrtInfo.bPreView = FALSE;
605- PrtInfo.bNum = bNum; // 行番号印刷(Booleanではない)
606- PrtInfo.bShortBinding = nBinding; // 綴じ方向(-1:サーバ)
607- PrtInfo.nSingleLine = nSingleLine; // 折り返し動作
608-
609- // 作業ファイルを作成する
610- strcpy(PrtInfo.szFileName, PrtInfo.szTitle);
611- if (NULL == (fp = MakeTempFile("wt", PrtInfo.szFileName))) {
612- return FALSE;
613- }
614- fclose(fp);
615-
616- // ファイルを複写する
617- if (!CopyFile(lpszFileName, PrtInfo.szFileName, FALSE)) {
618- Syslog(TRUE, "%s#%d: %s %s", __FILE__, __LINE__,
619- GetLastErrorMessage("GetFileAttributes()",
620- GetLastError()),
621- PrtInfo.szFileName);
622- return FALSE;
623- }
624-
625- return SendPrintData(hWnd, &PrtInfo);
626-}
627-
628-/*--------------------------------------------------------------------
629- * UNIXのSyslogの簡易版。常にdebug.local7しか出力しません。
630- * *-------------------------------------------------------------------*/
631-VOID WINAPI
632-Syslog(
633- BOOL bStdOut, // T:stdoutにも出力
634- LPCSTR lpstr, // 書式printfと同じ
635- ... // 引数
636- )
637-{
638- WSADATA wsaData;
639- SOCKET finet;
640- PSERVENT sp;
641- SOCKADDR_IN sin;
642- LPHOSTENT lpHost;
643- va_list args; // 引数展開用
644- char szLine[1024 * 64], szBuf[1024], *p;
645-
646- // モジュール名のフルパスを得る
647- if (!GetModuleFileName(GetModuleHandle(NULL), szBuf, 1024)) {
648- return;
649- }
650- // ファイル名部分だけ切り出す
651- if (NULL == (p = strrchr(szBuf, '\\'))) {
652- return;
653- }
654- // FACILITY = 23, LEVEL = 7
655- sprintf(szLine, "<%d>[%s] ", 7 + 23 * 8, p + 1);
656-
657- // 文字列を書式に合せて整形する
658- va_start(args, lpstr);
659- vsprintf(szLine + strlen(szLine), lpstr, args);
660- va_end(args);
661-
662- if (bStdOut) {
663- printf("%s\n", szLine);
664- }
665-
666- if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
667- return;
668- }
669-
670- if (0 > (finet = socket(AF_INET, SOCK_DGRAM, 0))) {
671- return;
672- }
673-
674- lpHost = gethostbyname("localhost");
675-
676- if (NULL == (sp = getservbyname("syslog", "udp"))) {
677- return;
678- }
679-
680- memset(&sin, 0, sizeof(sin));
681- sin.sin_family = AF_INET;
682- sin.sin_port = htons(sp->s_port);
683- sin.sin_addr = *((LPIN_ADDR)*lpHost->h_addr_list);
684-
685- sendto(finet, szLine, strlen(szLine), 0, (PSOCKADDR)&sin,
686- sizeof(SOCKADDR));
687- closesocket(finet);
688- WSACleanup();
689-}
690-
691-/*--------------------------------------------------------------------
692- * 指定可能な用紙サイズの一覧を返却する。
693- *
694- * *-------------------------------------------------------------------*/
695-LPTSTR WINAPI
696-GetPaperSizeUsageMessage()
697-{
698- int i;
699- static TCHAR buf[4096];
700-
701- strcpy(buf, "用紙サイズは以下の何れかを指定して下さい。"
702- "但し, 全てのオプションが全てのプリンタで"
703- "有効とは限りません。\n\n"
704- "オプション 説明\n"
705- "------------------- ------------------------------\n");
706- for (i = 0; devModePs[i].cmdOpt; i++) {
707- sprintf(buf + strlen(buf), "%-20s%s\n",
708- devModePs[i].cmdOpt, devModePs[i].sComment);
709- if (strlen(buf) > (4096 - 80)) {
710- break;
711- }
712- }
713- return buf;
714-}
715-
716-/*--------------------------------------------------------------------
717- * コマンドオプションで指定した用紙サイズから、DEVMODEで使用する用紙サ
718- * イズの定数を得る。用紙サイズが不正の場合は0を返却する。
719- * *-------------------------------------------------------------------*/
720-short WINAPI
721-GetPaperSizeDevMode(LPTSTR cmdOpt)
722-{
723- int i;
724- for (i = 0; devModePs[i].cmdOpt; i++) {
725- if (0 == stricmp(cmdOpt, devModePs[i].cmdOpt)) {
726- return devModePs[i].dmPaperSize;
727- }
728- }
729- return 0;
730-}
731-/*--------------------------------------------------------------------
732- * DEVMODEで使用する用紙サイズの定数から用紙サイズの説明を得る。
733- * *-------------------------------------------------------------------*/
734-LPCTSTR WINAPI
735-GetPaperSizeComment(short dmPaperSize)
736-{
737- int i;
738-
739- if (0 == dmPaperSize) {
740- return (LPCTSTR)"デフォルト";
741- }
742- for (i = 0; devModePs[i].cmdOpt; i++) {
743- if (dmPaperSize == devModePs[i].dmPaperSize) {
744- return (LPCTSTR)devModePs[i].sComment;
745- }
746- }
747- return (LPCTSTR)"不明";
748-}
749-/*--------------------------------------------------------------------
750- * PostScript ファイルから、Titleを得る。
751- * *-------------------------------------------------------------------*/
752-#define PS_TITLE_STR "%%Title:"
753-
754-LPCTSTR WINAPI
755-GetPSTitle(LPCTSTR lpszFile, // PSファイル名
756- LPTSTR lpszTitle, // タイトル格納エリア
757- int cbMax // 格納最大文字数
758- )
759-{
760- FILE *fp;
761- TCHAR szBuf[1024], *p;
762-
763- memset(lpszTitle, 0, cbMax);
764-
765- if (NULL == (fp = fopen(lpszFile, "rt"))) {
766- Syslog(TRUE, "%s#%d: PSファイル[%s]をオープンできません(%s)",
767- __FILE__, __LINE__, lpszFile, strerror(0));
768- return NULL;
769- }
770-
771- while (fgets(szBuf, 1024, fp)) {
772- if (p = strstr(szBuf, PS_TITLE_STR)) {
773- break;
774- }
775- }
776- fclose(fp);
777- if (p) {
778- strncpy(lpszTitle, p + strlen(PS_TITLE_STR), cbMax);
779- } else {
780- strncpy(lpszTitle, "unclear title", cbMax);
781- }
782- TrimString(lpszTitle);
783- Syslog(FALSE, "DBG:GetPSTitle[%s]", lpszTitle);
784- return (LPCTSTR)lpszTitle;
785-}
15+ *
16+ * Revision 1.19 2004/06/18 00:57:57 tfuruka1
17+ * 改行コードの修正のみです。
18+ *
19+ * Revision 1.18 2004/01/12 09:58:24 tfuruka1
20+ * 長辺綴じと短辺綴じに対応しました。
21+ *
22+ * Revision 1.17 2004/01/11 11:48:06 tfuruka1
23+ * 作業ファイルの作成ルーチンにSyslogを追加しました。
24+ *
25+ * Revision 1.16 2004/01/11 10:52:37 tfuruka1
26+ * バッファ名にリダイレクト記号 (aaa<3>等)が含まれていると作業ファイル
27+ * の作成に失敗していた問題を修正しました。
28+ *
29+ * Revision 1.15 2003/04/11 21:40:44 tfuruka1
30+ * GetLongBaseName関数で自動変数のポインタを返却していたバグを修正(露見
31+ * していなかったが、メモリ破壊をおこす可能性あり)
32+ *
33+ * Revision 1.14 2003/03/29 12:43:59 tfuruka1
34+ * ● SendPrintFromStdin関数でクリップボードの内容を読み込む処理を追加し
35+ * た。
36+ *
37+ * Revision 1.13 2003/03/14 15:06:19 tfuruka1
38+ * ● Syslog関数の仕様変更に伴い、Syslog関数を使用している部分の修正を行っ
39+ * た。
40+ * ● 作業ファイルの作成ルールを一部変更した(.を_に変更)。Distillerが作成
41+ * するPDFファイルが、拡張子以降を無視するので、出力ファイル名が重複す
42+ * るのを避けるのが目的である。
43+ * ● サーバの起動関数に、サーバの起動オプションを追加した。
44+ * ● Syslog関数の仕様を変更した。第一パラメータに標準出力オプションを追
45+ * 加した。
46+ * ● PostScriptファイルからタイトルを取得する関数を追加した。
47+ *
48+ * Revision 1.12 2003/03/01 09:01:25 tfuruka1
49+ * ● 作業ファイルの作成処理において、ファイル名に使用出来ない文字が指定去
50+ * れた場合に適切な文字に変更するように修正を行った。
51+ *
52+ * Revision 1.11 2003/02/25 15:28:35 tfuruka1
53+ * 行番号印刷の処理追加による対応を行った。
54+ *
55+ * Revision 1.10 2001/12/23 10:23:33 tfuruka1
56+ * ●作業ディレクトリ名取得の関数を新規追加(作業ファイル作成関数から切り出
57+ * し)
58+ *
59+ * Revision 1.9 2001/12/17 14:33:17 tfuruka1
60+ * syslog内部で標準出力へ出力していた処理を削除した(やっぱりうっとうしい
61+ * ので)。
62+ *
63+ * Revision 1.8 2001/12/14 17:04:43 tfuruka1
64+ * プレビュー対応
65+ *
66+ * Revision 1.7 2001/12/08 15:19:06 tfuruka1
67+ * 用紙サイズの指定対応の対応漏れの対応。
68+ *
69+ * Revision 1.6 2001/12/07 18:25:11 tfuruka1
70+ * 用紙サイズの指定を出来るようにした。
71+ *
72+ * Revision 1.5 2001/10/01 13:20:47 tfuruka1
73+ * 用紙の向きを指定出来るように修正。
74+ *
75+ * Revision 1.4 2001/08/19 04:35:57 tfuruka1
76+ * PostScriptファイルの暫定対応(ただ単にDistillerの監視フォルダに放り込
77+ * むだけ)。
78+ *
79+ * Revision 1.3 2001/08/18 16:30:30 tfuruka1
80+ * ●作業ファイルの作成に_mktemp関数を使用していたが、よく考えたらこの関
81+ * 数は、最大で 27 個しか一意なファイル名を作成できない事に気が付いた
82+ * (というか、エラーが出た)ので、_mktempのbaseが極力一意になるように
83+ * して、27個以上の一意なファイルを作成できるようにした。
84+ * ●MessageBoxを使用している部分をSyslogを使用するように変更した(Meadow
85+ * から呼ばれた時にMessageBoxを使用すると、Windowが見えないのでダイアロ
86+ * グを閉じる事ができなくなるので)。
87+ * ●SendPrintFromFile関数を廃止し、SendPrintFromFileCopy関数に統合した。
88+ * ●Syslog関数で、標準出力にも出力するようにした(syslogdがなくてもデ
89+ * バッグできる)。
90+ *
91+ * Revision 1.2 2001/02/05 17:38:02 tfuruka1
92+ * RCSがおかしくなったので、復旧した。過去の修正内容は以下の通り。
93+ * ●標準入力から読み込んだバイト数がゼロの場合は処理を行わないように修正
94+ * した。
95+ * ●Syslog関数を追加した。主な目的はデバッグ用である。
96+ * ●GetLongBaseName関数を追加した。
97+ *
98+ * Revision 1.1 2001/02/05 17:35:32 tfuruka1
99+ * Initial revision
100+ *
101+ *
102+ */
103+// (replace-regexp "[ \t]+$" "")
104+#include "ak2prs.h"
105+#include "ak2pr.h"
106+
107+/* 用紙サイズの一覧 */
108+static struct {
109+ LPTSTR cmdOpt; // コマンドパラメータ等
110+ short dmPaperSize; // DEVMODEのパラメータ
111+ LPTSTR sComment; // 用紙の説明
112+} devModePs[] = {
113+ {"A3", DMPAPER_A3, "A3シート, 297×420ミリメートル"},
114+ {"A4", DMPAPER_A4, "A4シート, 210×297ミリメートル"},
115+ {"A4SMALL", DMPAPER_A4SMALL, "A4 small シート, 210×297ミリメートル"},
116+ {"A5", DMPAPER_A5, "A5シート, 148×210ミリメートル"},
117+ {"B4", DMPAPER_B4, "B4シート, 250×354ミリメートル"},
118+ {"B5", DMPAPER_B5, "B5シート, 182×257ミリメートル"},
119+ {"LETTER", DMPAPER_LETTER, "Letter, 8 1/2×11インチ"},
120+ {"LEGAL", DMPAPER_LEGAL, "Legal, 8 1/2×14インチ"},
121+ {"CSHEET", DMPAPER_CSHEET, "C シート, 17×22インチ"},
122+ {"DSHEET", DMPAPER_DSHEET, "D シート, 22×34インチ"},
123+ {"ESHEET", DMPAPER_ESHEET, "E シート, 34×44インチ"},
124+ {"LETTERSMALL", DMPAPER_LETTERSMALL, "Letter Small, 8 1/2×11インチ"},
125+ {"TABLOID", DMPAPER_TABLOID, "Tabloid, 11×17インチ"},
126+ {"LEDGER", DMPAPER_LEDGER, "Ledger, 17×11インチ"},
127+ {"STATEMENT", DMPAPER_STATEMENT, "Statement, 5 1/2×8 1/2インチ"},
128+ {"EXECUTIVE", DMPAPER_EXECUTIVE, "Executive, 7 1/4×10 1/2インチ"},
129+ {"FOLIO", DMPAPER_FOLIO, "Folio, 8 1/2×13インチ"},
130+ {"QUARTO", DMPAPER_QUARTO, "Quarto, 215×275ミリメートル"},
131+ {"10X14", DMPAPER_10X14, "10×14インチシート"},
132+ {"11X17", DMPAPER_11X17, "11×17インチシート"},
133+ {"NOTE", DMPAPER_NOTE, "Note, 8 1/2×11インチ"},
134+ {"ENV_9", DMPAPER_ENV_9, "#9 Envelope, 3 7/8×8 7/8インチ"},
135+ {"ENV_10", DMPAPER_ENV_10, "#10 Envelope, 4 1/8×9 1/2インチ"},
136+ {"ENV_11", DMPAPER_ENV_11, "#11 Envelope, 4 1/2×10 3/8インチ"},
137+ {"ENV_12", DMPAPER_ENV_12, "#12 Envelope, 4 3/4×11インチ"},
138+ {"ENV_14", DMPAPER_ENV_14, "#14 Envelope, 5×11 1/2インチ"},
139+ {"ENV_DL", DMPAPER_ENV_DL, "DL Envelope, 110×220ミリメートル"},
140+ {"ENV_C5", DMPAPER_ENV_C5, "C5 Envelope, 162×229ミリメートル"},
141+ {"ENV_C3", DMPAPER_ENV_C3, "C3 Envelope, 324×458ミリメートル"},
142+ {"ENV_C4", DMPAPER_ENV_C4, "C4 Envelope, 229×324ミリメートル"},
143+ {"ENV_C6", DMPAPER_ENV_C6, "C6 Envelope, 114×162ミリメートル"},
144+ {"ENV_C65", DMPAPER_ENV_C65, "C65 Envelope, 114×229ミリメートル"},
145+ {"ENV_B4", DMPAPER_ENV_B4, "B4 Envelope, 250×353ミリメートル"},
146+ {"ENV_B5", DMPAPER_ENV_B5, "B5 Envelope, 176×250ミリメートル"},
147+ {"ENV_B6", DMPAPER_ENV_B6, "B6 Envelope, 176×125ミリメートル"},
148+ {"ENV_ITALY", DMPAPER_ENV_ITALY, "Italy Envelope, 110×230ミリメートル"},
149+ {"ENV_MONARCH", DMPAPER_ENV_MONARCH,
150+ "Monarch Envelope, 3 7/8×7 1/2インチ"},
151+ {"ENV_PERSONAL", DMPAPER_ENV_PERSONAL,
152+ "6 3/4 Envelope, 3 5/8×6 1/2インチ"},
153+ {"FANFOLD_US", DMPAPER_FANFOLD_US, "US Std Fanfold, 14 7/8×11インチ"},
154+ {"FANFOLD_STD_GERMAN", DMPAPER_FANFOLD_STD_GERMAN,
155+ "German Std Fanfold, 8 1/2×12インチ"},
156+ {"FANFOLD_LGL_GERMAN", DMPAPER_FANFOLD_LGL_GERMAN,
157+ "German Legal Fanfold, 8 1/2×13インチ"},
158+ {NULL, 0, NULL}
159+};
160+
161+/*--------------------------------------------------------------------
162+ * dwErr で指定されたエラーコードに対応するエラーメッセージを関数にシ
163+ * ステムメッセージテーブルリソースから検索して一時的な文字列へのポイ
164+ * ンタを返却する。dwErr は GetLastError から得た値を指定する事。lpsz
165+ * はエラーメッセージへ追加する文字列を指定する。API 名等を指定する。
166+ * *-------------------------------------------------------------------*/
167+LPCSTR WINAPI
168+GetLastErrorMessage(LPCSTR lpsz, DWORD dwErr)
169+{
170+#ifdef _WIN32_WCE
171+ static LPTSTR sz = "WindowsCE では GetLastErrorMessage はみサポートです";
172+ return sz;
173+#else
174+ static char sz[1024];
175+ char szTmp[256];
176+ int i;
177+
178+ if (!(i = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
179+ FORMAT_MESSAGE_IGNORE_INSERTS,
180+ NULL, dwErr, 0, szTmp, sizeof(szTmp), NULL))) {
181+ strcpy(szTmp, "---");
182+ }
183+ else {
184+ szTmp[i] = '\0';
185+ for (i--; 0 <= i; i--) {
186+ if ('\n' == szTmp[i] || '\r' == szTmp[i]) {
187+ szTmp[i] = '\0';
188+ }
189+ }
190+ }
191+ wsprintf(sz, "[WIN32] %s: Error Code = %d(%#02x): %s",
192+ lpsz, dwErr, dwErr, szTmp);
193+ return (LPCTSTR)sz;
194+#endif
195+}
196+
197+/*--------------------------------------------------------------------
198+ * 作業用ディレクトリ名を得る。作業ディレクトリ名は書き換えてはいけま
199+ * せん。
200+ * *-------------------------------------------------------------------*/
201+LPCTSTR WINAPI
202+GetTempDirectoryName()
203+{
204+ static TCHAR szTempDirName[MAX_PATH] = "\0";
205+ char *p1;
206+ DWORD dwFA;
207+ int i;
208+
209+ if (NULL == (p1 = getenv("TEMP"))) {
210+ Syslog(TRUE, "%s#%d: 環境変数TEMPが見つかりません",
211+ __FILE__, __LINE__);
212+ return NULL;
213+ }
214+
215+ for (i = 0; i < 100; i++) {
216+ sprintf(szTempDirName, "%s\\ak2prTempDir%d", p1, i);
217+ if (0xFFFFFFFF == (dwFA = GetFileAttributes(szTempDirName))) {
218+ if (0 != _mkdir(szTempDirName)) {
219+ continue;
220+ }
221+ break;
222+ }
223+ if (dwFA & FILE_ATTRIBUTE_DIRECTORY) {
224+ break;
225+ }
226+ }
227+ if (100 <= i) {
228+ Syslog(TRUE, "%s#%d: 作業ディレクトリが作成できません",
229+ __FILE__, __LINE__);
230+ szTempDirName[0] ='\0';
231+ return NULL;
232+ }
233+ return (LPCTSTR)szTempDirName;
234+}
235+
236+/*--------------------------------------------------------------------
237+ * 作業ファイルを作成する。正常に作成出来た場合はファイルポインタを返
238+ * 却する。作成できなかった場合は NULL を返却する。mode は fopen の
239+ * mode と全く同じである。また, ファイルを使用し終った後は fclose でファ
240+ * イルをクローズ後, lpszFileName で返却したファイルを削除しなければな
241+ * らない。どうやら、dll内で作成したファイルポインタを呼出し元で使用す
242+ * ると、アクセスヴァイオレーションが発生するようなので、使用時には要
243+ * 注意。
244+ * *-------------------------------------------------------------------*/
245+FILE * WINAPI
246+MakeTempFile(
247+ IN const char *mode, // モード
248+ IN OUT LPTSTR lpszFileName // 作成した作業ファイル名
249+ )
250+{
251+ static int iCnt = 0;
252+ FILE *fp;
253+ time_t t;
254+ TCHAR szFileName[MAX_PATH];
255+ LPCTSTR lpszDir;
256+ int i;
257+
258+ // ファイル名に * や \ 等が含まれていると、正しいファイルを作成で
259+ // きないので、適切な文字に置き換える
260+ Syslog(FALSE, "MakeTempFile Request filename: %s", lpszFileName);
261+ for (i = 0; *(lpszFileName + i); i++) {
262+ // 漢字の一バイト目の場合は次の文字もスキップする
263+ if (IsKanjiSJIS(*((LPBYTE)lpszFileName + i))) {
264+ i++;
265+ continue;
266+ }
267+ switch (*(lpszFileName + i)) {
268+ case '*':
269+ case '?':
270+ case '/':
271+ case ':':
272+ case '\\':
273+ case '<':
274+ case '>':
275+ *(lpszFileName + i) = '#';
276+ break;
277+ case ' ':
278+ *(lpszFileName + i) = '-';
279+ break;
280+ case '.': // Distillerが拡張子と
281+ // 判断するので
282+ *(lpszFileName + i) = '_';
283+ break;
284+ }
285+ }
286+
287+ if (!(lpszDir = GetTempDirectoryName())) {
288+ return NULL;
289+ }
290+
291+ iCnt++;
292+ iCnt %= 256;
293+
294+ t = time(NULL);
295+
296+ strncpy(szFileName, lpszFileName, MAX_PATH);
297+ sprintf(lpszFileName, "%s\\%s~%08x_%d_XXXXXX",
298+ lpszDir, szFileName, t, iCnt);
299+ Syslog(FALSE, "MakeTempFile Response filename: %s", lpszFileName);
300+ if (!_mktemp(lpszFileName)) {
301+ Syslog(TRUE, "%s#%d: 作業ファイルが作成できません",
302+ __FILE__, __LINE__);
303+ return NULL;
304+ }
305+ if (NULL == (fp = fopen(lpszFileName, mode))) {
306+ Syslog(TRUE, "%s#%d: 作業ファイル[%s]をオープンできません(%s)",
307+ __FILE__, __LINE__, lpszFileName, strerror(0));
308+ return NULL;
309+ }
310+ return fp;
311+}
312+
313+/*--------------------------------------------------------------------
314+ * MakeTempFileと同じですが、ファイルを作成するだけで、ファイルポイン
315+ * タは返却しません。ファイルもクローズ状態です。
316+ * *-------------------------------------------------------------------*/
317+BOOL WINAPI
318+MakeTempFileAndClose(
319+ IN const char *mode, // モード
320+ IN OUT LPTSTR lpszFileName // 作成した作業ファイル名
321+ )
322+{
323+ FILE *fp;
324+
325+ if (!(fp = MakeTempFile(mode, lpszFileName))) {
326+ return FALSE;
327+ }
328+ fclose(fp);
329+ return TRUE;
330+}
331+
332+/*--------------------------------------------------------------------
333+ * 自分自身が格納されているディレクトリ名への一時的なポインタを得る。
334+ * 返却するポインタは一時的なものなので, 必要な場合は複写して使用する
335+ * 事。
336+ * *-------------------------------------------------------------------*/
337+LPCTSTR WINAPI
338+GetMyDir(VOID)
339+{
340+ static TCHAR szBuf[1024];
341+ char *p1, *p2;
342+
343+ // ファイルのフルパスを得る
344+ if (!GetModuleFileName(GetModuleHandle(NULL), szBuf, 1024)) {
345+ int nErr = GetLastError();
346+ Syslog(TRUE, "%s#%d: %s", __FILE__, __LINE__,
347+ GetLastErrorMessage("GetModuleHandle", nErr));
348+ return NULL;
349+ }
350+
351+ p1 = strrchr(szBuf, '\\');
352+ p2 = strrchr(szBuf, '/');
353+ p1 = ((ULONG)p1 > (ULONG)p2) ? p1 : p2;
354+ if (!p1) {
355+ strcpy(szBuf, "./");
356+ }
357+ else {
358+ *(p1 + 1) = '\0';
359+ }
360+ return (LPCTSTR)szBuf;
361+}
362+
363+/*--------------------------------------------------------------------
364+ * Unixのbasenameと同じ。返却するポインタは一時的なポインタなので、必
365+ * ずコピーして使用する必要がある。
366+ * *-------------------------------------------------------------------*/
367+LPCTSTR WINAPI
368+BaseName(LPCTSTR lpszPath)
369+{
370+ LPCTSTR a, b;
371+
372+ a = _mbsrchr(lpszPath, '\\');
373+ b = _mbsrchr(lpszPath, '/');
374+
375+ if (a == b) { // 等しい時は NULLしかない
376+ return lpszPath;
377+ }
378+
379+ return ((ULONG)a > (ULONG)b ? a : b) + 1;
380+}
381+LPCTSTR WINAPI
382+GetLongBaseName(LPCTSTR lpszPath)
383+{
384+ HANDLE hFile;
385+ static WIN32_FIND_DATA wfd;
386+
387+ hFile = FindFirstFile(lpszPath, &wfd);
388+ if (INVALID_HANDLE_VALUE == hFile) {
389+ return BaseName(lpszPath);
390+ }
391+ FindClose(hFile);
392+ return wfd.cFileName;
393+}
394+
395+/*--------------------------------------------------------------------
396+ * プリントサーバが起動しているかチェックする。起動していた場合は HWND
397+ * を返却する。未起動の場合は NULL を返す。
398+ * *-------------------------------------------------------------------*/
399+BOOL WINAPI
400+IsPrtServerEnable(VOID)
401+{
402+ return (BOOL)FindWindow(SV_CLASS, SV_CAPTION);
403+}
404+
405+/*--------------------------------------------------------------------
406+ * プリントサーバを起動する。正常に起動出来た場合は TRUE を返却する。起
407+ * 動できなかった場合は FALSE を返す。
408+ * *-------------------------------------------------------------------*/
409+BOOL WINAPI
410+ExecutePrtServer(LPCTSTR lpszOption)
411+{
412+ PROCESS_INFORMATION pi; // プロセス情報
413+ STARTUPINFO sui; // 起動情報
414+ TCHAR szImageName[1024]; // モジュール名
415+ LPCTSTR lpszMyDir; // 自分のディレクトリ
416+ int i; // 汎用
417+
418+ if (IsPrtServerEnable()) // 既に起動していた場合は
419+ return TRUE; // 正常に起動したものとする
420+
421+ if (!(lpszMyDir = GetMyDir())) { // 自分自身のディレクトリを得る
422+ return FALSE;
423+ }
424+
425+ // 実行ファイルを作成する
426+ sprintf(szImageName, "%s/%s %s", lpszMyDir, SV_EXE_NAME, lpszOption);
427+
428+ // プロセス情報と起動情報の初期化
429+ memset(&sui, 0, sizeof(STARTUPINFO));
430+ memset(&pi, 0, sizeof(PROCESS_INFORMATION));
431+ sui.cb = sizeof(STARTUPINFO);
432+ sui.dwFlags = STARTF_USESHOWWINDOW;
433+ sui.wShowWindow = SW_SHOWNORMAL;
434+
435+ if (!CreateProcess(NULL, szImageName, NULL, NULL, FALSE,
436+ 0, NULL, NULL, &sui, &pi )) {
437+ int nErr = GetLastError();
438+ Syslog(TRUE, "%s#%d: %s", __FILE__, __LINE__,
439+ GetLastErrorMessage("CreateProcess", nErr));
440+ return FALSE;
441+ }
442+
443+ // WaitForInputIdle(pi.hProcess, INFINITE);
444+ // ウィンドウが生々されるまで待つ
445+ for (i = 0; i < 10; i++) {
446+ if (IsPrtServerEnable()) {
447+ break;
448+ }
449+ Sleep(1000);
450+ }
451+ // プロセスハンドルは必要無いので閉じる
452+ CloseHandle(pi.hProcess);
453+
454+ if (pi.hThread) { // スレッドハンドルも閉じる
455+ CloseHandle(pi.hThread);
456+ }
457+
458+ // もう一度サーバーをチェックする
459+ if (!IsPrtServerEnable()) {
460+ Syslog(TRUE, "%s#%d: サーバの起動に失敗したようです",
461+ __FILE__, __LINE__);
462+ return FALSE;
463+ }
464+ return TRUE; // 正常起動
465+}
466+
467+/*--------------------------------------------------------------------
468+ * プリントサーバへ印刷情報を送信する。
469+ * *-------------------------------------------------------------------*/
470+static BOOL WINAPI
471+SendPrintData(
472+ HWND hWnd, // 送信元のハンドル
473+ PPRT_INFO pPrtInfo // 印刷情報
474+ )
475+{
476+ HWND hWndTo; // 送信先のハンドル
477+ COPYDATASTRUCT cds; // 送信データ
478+
479+ if (!ExecutePrtServer(NULL)) { // プリンタサーバを起動
480+ return FALSE; // サーバが居ない
481+ }
482+
483+ // DLLのVarsion不一致を防ぐ為, タイムスタンプを埋める
484+ strcpy(pPrtInfo->szTimeStamp, TIMESTAMP);
485+ strcpy(pPrtInfo->szTimeStamp1, TIMESTAMP);
486+
487+ // サーバのハンドルを得る
488+ if (!(hWndTo = FindWindow(SV_CLASS, SV_CAPTION))) {
489+ int nErr = GetLastError();
490+ Syslog(TRUE, "%s#%d: %s", __FILE__, __LINE__,
491+ GetLastErrorMessage("FindWindow", nErr));
492+ return FALSE;
493+ }
494+
495+ // 送信データを設定する
496+ cds.dwData = 0;
497+ cds.cbData = sizeof(PRT_INFO);
498+ cds.lpData = (LPVOID)pPrtInfo;
499+
500+ // 印刷情報を送信する
501+ return SendMessage(hWndTo, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
502+}
503+
504+/*--------------------------------------------------------------------
505+ * 標準入力の内容を読み込みプリントサーバへ印刷情報を送信する。標準入
506+ * 力の代わりにクリップボードからテキストを読み込む事も可能である。
507+ * *-------------------------------------------------------------------*/
508+BOOL WINAPI
509+SendPrintFromStdin(
510+ BOOL bClipBoard, // T:クリップボード
511+ HWND hWnd, // ハンドル
512+ LPCTSTR lpszTitle, // タイトル未指定時は"stdin"
513+ int nNumOfUp, // 段組数
514+ int nTab, // タブ幅
515+ double fFontSize, // フォントサイズ
516+ int nType, // 印刷データタイプ
517+ int nOrientation, // 用紙の向き
518+ short dmPaperSize, // 用紙サイズ
519+ int bNum, // 行番号の印刷
520+ int nBinding, // 綴じ方向
521+ int nSingleLine // 折り返し動作
522+ )
523+{
524+ PRT_INFO PrtInfo; // プリントファイル情報
525+ FILE *fp; // ファイルポインタ
526+ TCHAR szBuf[1024]; // 標準入力用バッファ
527+ BOOL bNotZero = FALSE; // ファイルサイズゼロ
528+
529+ // プリントファイル情報の初期化
530+ memset((LPVOID)&PrtInfo, 0, sizeof(PRT_INFO));
531+ if (lpszTitle) {
532+ strncpy(PrtInfo.szTitle, lpszTitle, 255);
533+ } else {
534+ strcpy(PrtInfo.szTitle, bClipBoard ? "Clipboard" : "stdin");
535+ }
536+
537+ PrtInfo.nNumOfUp = nNumOfUp;
538+ PrtInfo.nTab = nTab;
539+ PrtInfo.nType = nType;
540+ PrtInfo.fFontSize = fFontSize;
541+ PrtInfo.nOrientation = nOrientation;
542+ PrtInfo.dmPaperSize = dmPaperSize;
543+ PrtInfo.bPreView = FALSE;
544+ PrtInfo.bNum = bNum; // 行番号の印刷(-1:サーバ)
545+ PrtInfo.bShortBinding = nBinding; // 綴じ方向(-1:サーバ)
546+ PrtInfo.nSingleLine = nSingleLine; // 折り返し動作
547+
548+ // 作業ファイルを作成する
549+ strcpy(PrtInfo.szFileName, PrtInfo.szTitle);
550+ if (NULL == (fp = MakeTempFile("wt", PrtInfo.szFileName))) {
551+ return FALSE;
552+ }
553+
554+ if (bClipBoard) {
555+ // クリップボードからファイルに読み込む
556+ bNotZero = ReadClipBoardToFP(NULL, fp);
557+ }
558+ else {
559+ // 標準入力から読み込む
560+ while (fgets(szBuf, 1024, stdin)) {
561+ fprintf(fp, "%s", szBuf);
562+ bNotZero++;
563+ }
564+ }
565+
566+ fclose(fp);
567+ if (!bNotZero) {
568+ unlink(PrtInfo.szFileName);
569+ Syslog(TRUE, "%s", "ファイルサイズが0なのでキャンセルします");
570+ return FALSE;
571+ }
572+
573+ return SendPrintData(hWnd, &PrtInfo);
574+}
575+
576+/*--------------------------------------------------------------------
577+ * 指定されたファイルを一時ファイルへ複写し,プリントサーバへ印刷情報
578+ * を送信する。
579+ * *-------------------------------------------------------------------*/
580+BOOL WINAPI
581+SendPrintFromFileCopy(
582+ HWND hWnd, // ハンドル
583+ LPCTSTR lpszTitle, // タイトル未指定時は"stdin"
584+ LPCTSTR lpszFileName, // コピー元ファイル名
585+ int nNumOfUp, // 段組数
586+ int nTab, // タブ幅
587+ double fFontSize, // フォントサイズ
588+ int nType, // 印刷データタイプ
589+ int nOrientation, // 用紙の向き
590+ short dmPaperSize, // 用紙サイズ
591+ int bNum, // 行番号印刷
592+ int nBinding, // 綴じ方向
593+ int nSingleLine // 折り返し動作
594+ )
595+{
596+ PRT_INFO PrtInfo; // プリントファイル情報
597+ FILE *fp; // ファイルポインタ
598+ DWORD dwFA; // ファイル情報
599+
600+ // ファイルの存在チェックを行う
601+ if (0xFFFFFFFF == (dwFA = GetFileAttributes(lpszFileName))) {
602+ LPCTSTR p;
603+ dwFA = GetLastError();
604+ p = GetLastErrorMessage("GetFileAttributes()", dwFA);
605+ Syslog(TRUE, "%s#%d: %s %s", __FILE__, __LINE__, p, lpszFileName);
606+ return FALSE;
607+ }
608+
609+ // ディレクトリの場合はエラー
610+ if (dwFA & FILE_ATTRIBUTE_DIRECTORY) {
611+ Syslog(TRUE, "%s#%d: %sはディレクトリです",
612+ __FILE__, __LINE__, lpszFileName);
613+ return FALSE;
614+ }
615+
616+ // プリントファイル情報の初期化
617+ memset((LPVOID)&PrtInfo, 0, sizeof(PRT_INFO));
618+ if (lpszTitle) {
619+ strncpy(PrtInfo.szTitle, lpszTitle, 255);
620+ } else {
621+ strncpy(PrtInfo.szTitle, GetLongBaseName(lpszFileName), 255);
622+ }
623+
624+ PrtInfo.nNumOfUp = nNumOfUp;
625+ PrtInfo.nTab = nTab;
626+ PrtInfo.nType = nType;
627+ PrtInfo.fFontSize = fFontSize;
628+ PrtInfo.nOrientation = nOrientation;
629+ PrtInfo.dmPaperSize = dmPaperSize;
630+ PrtInfo.bPreView = FALSE;
631+ PrtInfo.bNum = bNum; // 行番号印刷(Booleanではない)
632+ PrtInfo.bShortBinding = nBinding; // 綴じ方向(-1:サーバ)
633+ PrtInfo.nSingleLine = nSingleLine; // 折り返し動作
634+
635+ // 作業ファイルを作成する
636+ strcpy(PrtInfo.szFileName, PrtInfo.szTitle);
637+ if (NULL == (fp = MakeTempFile("wt", PrtInfo.szFileName))) {
638+ return FALSE;
639+ }
640+ fclose(fp);
641+
642+ // ファイルを複写する
643+ if (!CopyFile(lpszFileName, PrtInfo.szFileName, FALSE)) {
644+ Syslog(TRUE, "%s#%d: %s %s", __FILE__, __LINE__,
645+ GetLastErrorMessage("GetFileAttributes()",
646+ GetLastError()),
647+ PrtInfo.szFileName);
648+ return FALSE;
649+ }
650+
651+ return SendPrintData(hWnd, &PrtInfo);
652+}
653+
654+/*--------------------------------------------------------------------
655+ * UNIXのSyslogの簡易版。常にdebug.local7しか出力しません。
656+ * *-------------------------------------------------------------------*/
657+VOID WINAPI
658+Syslog(
659+ BOOL bStdOut, // T:stdoutにも出力
660+ LPCSTR lpstr, // 書式printfと同じ
661+ ... // 引数
662+ )
663+{
664+ WSADATA wsaData;
665+ SOCKET finet;
666+ PSERVENT sp;
667+ SOCKADDR_IN sin;
668+ LPHOSTENT lpHost;
669+ va_list args; // 引数展開用
670+ char szLine[1024 * 64], szBuf[1024], *p;
671+
672+ // モジュール名のフルパスを得る
673+ if (!GetModuleFileName(GetModuleHandle(NULL), szBuf, 1024)) {
674+ return;
675+ }
676+ // ファイル名部分だけ切り出す
677+ if (NULL == (p = strrchr(szBuf, '\\'))) {
678+ return;
679+ }
680+ // FACILITY = 23, LEVEL = 7
681+ sprintf(szLine, "<%d>[%s] ", 7 + 23 * 8, p + 1);
682+
683+ // 文字列を書式に合せて整形する
684+ va_start(args, lpstr);
685+ vsprintf(szLine + strlen(szLine), lpstr, args);
686+ va_end(args);
687+
688+ if (bStdOut) {
689+ printf("%s\n", szLine);
690+ }
691+
692+ if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
693+ return;
694+ }
695+
696+ if (0 > (finet = socket(AF_INET, SOCK_DGRAM, 0))) {
697+ return;
698+ }
699+
700+ lpHost = gethostbyname("localhost");
701+
702+ if (NULL == (sp = getservbyname("syslog", "udp"))) {
703+ return;
704+ }
705+
706+ memset(&sin, 0, sizeof(sin));
707+ sin.sin_family = AF_INET;
708+ sin.sin_port = htons(sp->s_port);
709+ sin.sin_addr = *((LPIN_ADDR)*lpHost->h_addr_list);
710+
711+ sendto(finet, szLine, strlen(szLine), 0, (PSOCKADDR)&sin,
712+ sizeof(SOCKADDR));
713+ closesocket(finet);
714+ WSACleanup();
715+}
716+
717+/*--------------------------------------------------------------------
718+ * 指定可能な用紙サイズの一覧を返却する。
719+ *
720+ * *-------------------------------------------------------------------*/
721+LPTSTR WINAPI
722+GetPaperSizeUsageMessage()
723+{
724+ int i;
725+ static TCHAR buf[4096];
726+
727+ strcpy(buf, "用紙サイズは以下の何れかを指定して下さい。"
728+ "但し, 全てのオプションが全てのプリンタで"
729+ "有効とは限りません。\n\n"
730+ "オプション 説明\n"
731+ "------------------- ------------------------------\n");
732+ for (i = 0; devModePs[i].cmdOpt; i++) {
733+ sprintf(buf + strlen(buf), "%-20s%s\n",
734+ devModePs[i].cmdOpt, devModePs[i].sComment);
735+ if (strlen(buf) > (4096 - 80)) {
736+ break;
737+ }
738+ }
739+ return buf;
740+}
741+
742+/*--------------------------------------------------------------------
743+ * コマンドオプションで指定した用紙サイズから、DEVMODEで使用する用紙サ
744+ * イズの定数を得る。用紙サイズが不正の場合は0を返却する。
745+ * *-------------------------------------------------------------------*/
746+short WINAPI
747+GetPaperSizeDevMode(LPTSTR cmdOpt)
748+{
749+ int i;
750+ for (i = 0; devModePs[i].cmdOpt; i++) {
751+ if (0 == stricmp(cmdOpt, devModePs[i].cmdOpt)) {
752+ return devModePs[i].dmPaperSize;
753+ }
754+ }
755+ return 0;
756+}
757+/*--------------------------------------------------------------------
758+ * DEVMODEで使用する用紙サイズの定数から用紙サイズの説明を得る。
759+ * *-------------------------------------------------------------------*/
760+LPCTSTR WINAPI
761+GetPaperSizeComment(short dmPaperSize)
762+{
763+ int i;
764+
765+ if (0 == dmPaperSize) {
766+ return (LPCTSTR)"デフォルト";
767+ }
768+ for (i = 0; devModePs[i].cmdOpt; i++) {
769+ if (dmPaperSize == devModePs[i].dmPaperSize) {
770+ return (LPCTSTR)devModePs[i].sComment;
771+ }
772+ }
773+ return (LPCTSTR)"不明";
774+}
775+/*--------------------------------------------------------------------
776+ * PostScript ファイルから、Titleを得る。
777+ * *-------------------------------------------------------------------*/
778+#define PS_TITLE_STR "%%Title:"
779+
780+LPCTSTR WINAPI
781+GetPSTitle(LPCTSTR lpszFile, // PSファイル名
782+ LPTSTR lpszTitle, // タイトル格納エリア
783+ int cbMax // 格納最大文字数
784+ )
785+{
786+ FILE *fp;
787+ TCHAR szBuf[1024], *p;
788+
789+ memset(lpszTitle, 0, cbMax);
790+
791+ if (NULL == (fp = fopen(lpszFile, "rt"))) {
792+ Syslog(TRUE, "%s#%d: PSファイル[%s]をオープンできません(%s)",
793+ __FILE__, __LINE__, lpszFile, strerror(0));
794+ return NULL;
795+ }
796+
797+ while (fgets(szBuf, 1024, fp)) {
798+ if (p = strstr(szBuf, PS_TITLE_STR)) {
799+ break;
800+ }
801+ }
802+ fclose(fp);
803+ if (p) {
804+ strncpy(lpszTitle, p + strlen(PS_TITLE_STR), cbMax);
805+ } else {
806+ strncpy(lpszTitle, "unclear title", cbMax);
807+ }
808+ TrimString(lpszTitle);
809+ Syslog(FALSE, "DBG:GetPSTitle[%s]", lpszTitle);
810+ return (LPCTSTR)lpszTitle;
811+}
--- a/src/dllmain.def
+++ b/src/dllmain.def
@@ -1,35 +1,38 @@
11 ; -*- mode: text; coding: sjis-dos; -*-
2-; Time-stamp: <2004-06-18 09:32:53 tfuruka1>
2+; Time-stamp: <2005-05-08 13:00:53 tfuruka1>
33 ;
4-; $Id: dllmain.def,v 1.3 2004/06/18 00:57:57 tfuruka1 Exp $
4+; $Id: dllmain.def,v 1.4 2005/05/08 13:01:00 tfuruka1 Exp $
55 ; $Log: dllmain.def,v $
6-; Revision 1.3 2004/06/18 00:57:57 tfuruka1
7-; 改行コードの修正のみです。
6+; Revision 1.4 2005/05/08 13:01:00 tfuruka1
7+; 作業ファイル作成関数を追加しました。従来のファイルポインタを返却する方
8+; 法だと、DLLにした時にアクセスバイオレーションが発生するので、ファイル
9+; 名のみを返却する関数を追加しました。
10+;
11+; Revision 1.3 2004/06/18 00:57:57 tfuruka1
12+; 改行コードの修正のみです。
813 ;
914 ; Revision 1.2 2003/03/29 13:53:35 tfuruka1
1015 ; ●GetPSTitleの追加
1116 ;
12-; Revision 1.1 2001/12/07 18:25:40 tfuruka1
13-; Initial revision
14-;
1517 ; Revision 1.1 1999/12/16 04:29:44 tfuruka1
1618 ; Initial revision
1719 ;
1820 EXPORTS
19- GetLastErrorMessage
20- IsPrtServerEnable
21- ExecutePrtServer
22- MakeTempFile
23- SendPrintFromStdin
24- SendPrintFromFileCopy
25- GetMyDir
26- BaseName
27- DbgPrint
28- DbgDump
29- Syslog
30- GetLongBaseName
31- GetPaperSizeUsageMessage
32- GetPaperSizeDevMode
33- GetPaperSizeComment
34- GetTempDirectoryName
35- GetPSTitle
21+ GetLastErrorMessage @1000
22+ IsPrtServerEnable @1010
23+ ExecutePrtServer @1020
24+ MakeTempFile @1030
25+ MakeTempFileAndClose @1040
26+ SendPrintFromStdin @1050
27+ SendPrintFromFileCopy @1060
28+ GetMyDir @1070
29+ BaseName @1080
30+ DbgPrint @1090
31+ DbgDump @1100
32+ Syslog @1110
33+ GetLongBaseName @1120
34+ GetPaperSizeUsageMessage @1130
35+ GetPaperSizeDevMode @1140
36+ GetPaperSizeComment @1150
37+ GetTempDirectoryName @1160
38+ GetPSTitle @1170