// String table and printout functions for WIN32
// tabsize = 8, lineends = LF, encoding = UTF-8
#include "peps.h"
#include <conio.h>
#include <shlwapi.h>
#ifdef UNICODE
#define MyLoadStringO(i,s,l) LoadString(0,i,s,l)
#else
// OEM-String laden
static int MyLoadStringO(UINT id, PSTR buf, int len) {
HRSRC r=FindResource(0,MAKEINTRESOURCE((id>>4)+1),RT_STRING);
PCWSTR p=(PCWSTR)LoadResource(0,r);
if (!p) return 0;
for (id&=15; id; id--) {
p+=*p+1;
}
len=WideCharToMultiByte(CP_OEMCP,0,p+1,*p,buf,len-1,NULL,NULL);
buf[len]=0;
return len;
}
#endif
#if _MSC_VER > 1400
static _declspec(noinline)
#endif
// ANSI- oder Unicode-String auf Konsole ausgeben (v.a. für Rahmensymbole)
// bei Umleitung ANSI- oder UTF8-Datei schreiben
void outConsole(PCTSTR s, DWORD l) {
if (_isatty(_fileno(stdout)))
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),s,l,&l,NULL); // Die Unicode-Funktion funktioniert für jede per <chcp> eingestellte Konsolen-Kodeseite
else{
#ifdef UNICODE
char u[4000];
DWORD x=WideCharToMultiByte(CP_UTF8,0,s,l,u,sizeof u,NULL,NULL);
fwrite(u,1,x,stdout);
#else
fwrite(s,1,l,stdout);
#endif
}
}
#if _MSC_VER > 1400
// Ohne "noinline" wirft der Linker vcprintf() in vrprintf() und benötigt __chkstk
static _declspec(noinline)
#endif
void vcprintf(PCTSTR t, va_list va) {
TCHAR s[2000];
outConsole(s,_vsntprintf(s,elemof(s),t,va));
}
void vrprintf(int id, va_list va) {
TCHAR t[2000];
MyLoadStringO(id,t,elemof(t));
vcprintf(t,va); // Stack aufteilen
}
void _cdecl rprintf(int id, ...) {
va_list va;
va_start(va,id);
vrprintf(id,va);
va_end(va);
}
extern int mygetch(bool noblock) {
int i=-1;
if (!noblock || _kbhit()) {
i=_getch(); // ASCII-Zeichen
if (!i || i==0xE0) i|=_getch()<<8; // Scancode (Cursortasten, F-Tasten)
} // Scancodes: F1=0x3B .. F10=0x44, ← ↑ → ↓ - unter Linux ganz anders!
return i;
}
// Je nach Argument wird
// - in einer Busy-Loop gewartet, bis die Zeit abgelaufen ist (< 2 ms)
// - Sleep() in einer Klammer aus timeBegin/EndPeriod() aufgerufen (<20 ms)
// - Sleep() aufgerufen, ohne in den Scheduler einzugreifen (sonst)
void usleep(DWORD us) {
if (us>=2000) {
if (us<20000) timeBeginPeriod(1);
Sleep(us/1000);
if (us<20000) timeEndPeriod(1);
}else{
LARGE_INTEGER freq, tic,toc;
QueryPerformanceFrequency(&freq);
freq.LowPart=MulDiv(freq.LowPart,us,1000000);
QueryPerformanceCounter(&tic);
do{
QueryPerformanceCounter(&toc);
}while (toc.LowPart-tic.LowPart < freq.LowPart);
}
}
static BOOL CALLBACK HandlerRoutine(DWORD reason) {
DoExit(45,reason);
return TRUE;
}
void InitRes() {
SetConsoleCtrlHandler(HandlerRoutine,TRUE);
}
void CALLBACK mainCRTStartup() {
extern void _cdecl main(int,TCHAR**);
int argc;
TCHAR **argv;
#ifdef UNICODE
argv = CommandLineToArgvW(GetCommandLine(),&argc);
#else // es gibt keine ANSI-Version davon,
// daher die undokumentierte MSVCRT.DLL-Version aufrufen
// Die ebenfalls exportierten Variablen __argc, __argv und __envp
// sind erst /nach/ Aufruf jener Funktion richtig gesetzt!
_CRTIMP void _cdecl __getmainargs(int*,char***,char***,void*,void*);
char **envp;
__getmainargs(&argc,&argv,&envp,NULL,&envp);
#endif
main(argc, argv);
}
/* Port access driver installation */
#ifdef _M_IX86
/*──────────────────────────────────────────────────────────────────────┐
│ Install/Remove eingebautes DirectNT.sys │
│ Die Datei DirectNT.sys ist in der Ressource (der Windows-Version) │
│ enthalten und wird bei Bedarf ausgepackt und installiert. │
│ Das klappt nicht: │
│ - bei fehlenden Admin-Rechten │
│ - bei aktiviertem Treiberzertifizierungszwang │
│ - bei 64-bit-Windows (da ist die .SYS-Datei auch nicht enthalten) │
├───────────────────────────────────────────────────────────────────────┤
│ Parameter: │
│ remove = false: installieren │
│ remove = true: alten Zustand wiederherstellen │
│ Rückgabe: │
└──────────────────────────────────────────────────────────────────────*/
extern bool InstallDirectNT(bool remove) {
bool ret = false;
static TCHAR SysFileName[MAX_PATH]; // static → zum Löschen der .SYS-Datei
static bool was_started; // static → beim Beenden anhalten oder auch nicht
SC_HANDLE hMgr = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (hMgr) {
SC_HANDLE hSrv = OpenService(hMgr,T("DirectNT"),SERVICE_ALL_ACCESS);
SERVICE_STATUS Status;
if (remove) {
if (hSrv) {
ret = was_started // nicht stoppen
|| ControlService(hSrv,SERVICE_CONTROL_STOP,&Status)
&& (!SysFileName[0] || DeleteFile(SysFileName) && DeleteService(hSrv));
CloseServiceHandle(hSrv);
}
}else{
if (!hSrv) {
HRSRC hFR = FindResource(0,MAKEINTRESOURCE(1),RT_RCDATA);
HGLOBAL hRes = LoadResource(0,hFR);
if (hRes) {
HANDLE hSys;
DWORD bw;
GetTempPath(elemof(SysFileName),SysFileName);
PathAppend(SysFileName,T("DirectNT.sys"));
hSys = CreateFile(SysFileName,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_TEMPORARY,0);
if (hSys) {
WriteFile(hSys,LockResource(hRes),SizeofResource(0,hFR),&bw,NULL);
CloseHandle(hSys);
hSrv = CreateService(hMgr,
T("DirectNT"), // name of service
T("DirectNT"), // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_KERNEL_DRIVER, // service type
SERVICE_DEMAND_START, // start type
SERVICE_ERROR_NORMAL, // error control type
SysFileName, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password
if (!hSrv) { // CreateService schlug fehl?
DeleteFile(SysFileName); // SYS-Datei löschen
SysFileName[0] = 0; // nicht noch einmal löschen
}
}
}
}
if (hSrv) {
ret = StartService (hSrv,0,NULL);
if (!ret && GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) ret=was_started=true;
CloseServiceHandle(hSrv);
}
}
CloseServiceHandle(hMgr);
}
return ret;
}
#else
void __chkstk() {};
#endif
// Portadresse beschaffen
// Funktioniert ab NT4, Win98, aber (für die 32-Bit-Echse) nicht unter Windows 8/64!
// Windows 8/64 verbietet 32-Bit-Programmen den Aufruf von CM_Get_First_Log_Conf().
#include <setupapi.h>
#include <cfgmgr32.h>
#include <devguid.h>
WORD GetParportAddr(int n) {
WORD start=0;
TCHAR SucheNach[16];
HDEVINFO Devs=SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS,NULL,0,DIGCF_PRESENT);
SP_DEVINFO_DATA devInfo;
int j;
devInfo.cbSize=sizeof(devInfo);
_sntprintf(SucheNach,elemof(SucheNach),T("LPT%d"),n+1);
for (j=0; SetupDiEnumDeviceInfo(Devs,j,&devInfo); j++) {
HKEY hKey;
TCHAR val[16];
DWORD valsize=sizeof(val);
LOG_CONF Config;
RES_DES resDes;
IO_RESOURCE ior;
if (CM_Open_DevNode_Key(devInfo.DevInst,KEY_QUERY_VALUE,0,RegDisposition_OpenExisting,&hKey,CM_REGISTRY_HARDWARE)) continue;
if (!RegQueryValueEx(hKey,T("PortName"),NULL,NULL,(LPBYTE)val,&valsize)
&& !lstrcmpi(val,SucheNach)
&& !CM_Get_First_Log_Conf(&Config,devInfo.DevInst,ALLOC_LOG_CONF)
&& !CM_Get_Next_Res_Des(&resDes,Config,ResType_IO,NULL,0)) {
if (!CM_Get_Res_Des_Data(resDes,&ior,sizeof(ior),0))
start = (WORD)ior.IO_Header.IOD_Alloc_Base;
CM_Free_Res_Des_Handle(resDes);
}
RegCloseKey(hKey);
if (start) break;
}
SetupDiDestroyDeviceInfoList(Devs);
return start;
}
Detected encoding: UTF-8 | 0
|