Last active
November 26, 2018 00:05
-
-
Save meitinger/fd5d3228c52f2ddc7bb87244afea035f to your computer and use it in GitHub Desktop.
Utility that waits for a (redirected) printer to become ready, sets it as default and launches a program.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Copyright (C) 2017-2018 Manuel Meitinger | |
* | |
* This program is free software: you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation, either version 2 of the License, or | |
* (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
#define STRICT | |
#include <Windows.h> | |
#pragma comment(linker, "/ENTRY:Run") | |
#pragma comment(linker, "/SUBSYSTEM:WINDOWS") | |
#pragma comment(lib, "Kernel32.lib") | |
#pragma comment(lib, "User32.lib") | |
#pragma comment(lib, "Winspool.lib") | |
#define MessageTitle L"..." | |
#define DefaultPrinterPrefix L"..." | |
#define NumberOfRetries 100 | |
#define ProgramToRun L"..." | |
#define DO(what, op) \ | |
if (!(op)) \ | |
{ \ | |
exitCode = GetLastError(); \ | |
MessageBoxW(NULL, L"Cannot " what L".", MessageTitle, MB_OK | MB_ICONERROR); \ | |
goto Cleanup; \ | |
} | |
void Run(void) | |
{ | |
UINT exitCode = ERROR_SUCCESS; | |
DWORD size = 0x1000; | |
LPPRINTER_INFO_4W printers = NULL; | |
BOOL found; | |
INT retry; | |
DWORD count; | |
BOOL success; | |
LPPRINTER_INFO_4W newPrinters; | |
LPWSTR printer; | |
INT offset; | |
LPWSTR cmdLine; | |
BOOL escaped; | |
LPWSTR newCmdLine = NULL; | |
STARTUPINFOW startup; | |
PROCESS_INFORMATION process = {NULL, NULL}; | |
DO(L"allocate buffer", printers = HeapAlloc(GetProcessHeap(), 0, size)); | |
found = FALSE; | |
retry = 0; | |
while (!found && retry < NumberOfRetries) | |
{ | |
DO(L"query printers", (success = EnumPrintersW(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, (LPBYTE)printers, size, &size, &count)) || GetLastError() == ERROR_INSUFFICIENT_BUFFER); | |
if (!success) | |
{ | |
DO(L"reallocate buffer", newPrinters = HeapReAlloc(GetProcessHeap(), 0, printers, size)); | |
printers = newPrinters; | |
continue; | |
} | |
while (count-- > 0) | |
{ | |
printer = printers[count].pPrinterName; | |
offset = 0; | |
while (DefaultPrinterPrefix[offset] && printer[offset] == DefaultPrinterPrefix[offset]) | |
{ | |
offset++; | |
} | |
if (!DefaultPrinterPrefix[offset]) | |
{ | |
SetDefaultPrinterW(printer); | |
found = TRUE; | |
break; | |
} | |
} | |
Sleep(1000); | |
retry++; | |
} | |
if (!found) | |
{ | |
MessageBoxW(NULL, L"Printer not found: " DefaultPrinterPrefix, MessageTitle, MB_OK | MB_ICONWARNING); | |
} | |
cmdLine = GetCommandLineW(); | |
escaped = FALSE; | |
offset = 0; | |
while (cmdLine[offset]) | |
{ | |
if (cmdLine[offset] == L'"') | |
{ | |
escaped = !escaped; | |
} | |
else if (!escaped && cmdLine[offset] <= L' ') | |
{ | |
break; | |
} | |
offset++; | |
} | |
DO(L"allocate cmd line", newCmdLine = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(ProgramToRun) + lstrlenW(cmdLine + offset) + 1) * sizeof(WCHAR))); | |
DO(L"set application", lstrcpyW(newCmdLine, ProgramToRun)); | |
DO(L"set arguments", lstrcatW(newCmdLine, cmdLine + offset)); | |
SecureZeroMemory(&startup, sizeof(startup)); | |
startup.cb = sizeof(startup); | |
DO(L"launch program", CreateProcessW(NULL, newCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &process)); | |
DO(L"wait for program", WaitForSingleObject(process.hProcess, INFINITE) == WAIT_OBJECT_0); | |
Cleanup: | |
if (process.hThread) | |
{ | |
CloseHandle(process.hThread); | |
} | |
if (process.hProcess) | |
{ | |
CloseHandle(process.hProcess); | |
} | |
if (newCmdLine) | |
{ | |
HeapFree(GetProcessHeap(), 0, newCmdLine); | |
} | |
if (printers) | |
{ | |
HeapFree(GetProcessHeap(), 0, printers); | |
} | |
ExitProcess(exitCode); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment